Codeforces Round #748 (Div. 3) E. Gardener and Tree
阿新 • • 發佈:2021-10-15
簡單的拓撲排序應用。
https://codeforces.com/contest/1593/problem/E
題意
給一顆樹,每次刪除當前樹所有的葉子結點,問刪除 \(k\) 輪後還剩多少點
Tutorial
由於一棵樹的深度最高是 \(O(n)\) 刪除葉子結點的過程又顯然是個拓撲排序裡去掉入度為 \(0\) 節點的操作,因此這題可以直接暴力而我居然想搞直徑
點選檢視程式碼
#include <algorithm> #include <bitset> #include <cmath> #include <cstdio> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <vector> typedef long long ll; #define endl '\n' #define P pair<int, int> #define eps 1e-8 #define IOS \ ios::sync_with_stdio(0); \ cin.tie(0); \ cout.tie(0); using namespace std; const int N = 4e5 + 5; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; typedef long long ll; vector<int> mp[N]; int vis[N], deg[N],n,m,k; int main() { IOS int T; cin>>T; while(T--){ cin >> n>>k; for(int i=0,u,v;i<n-1;i++){ cin>>u>>v; mp[u].push_back(v); mp[v].push_back(u); deg[u]++; deg[v]++; } int cnt = n; vector<int> now; vector<int> nxt; for(int i=1;i<=n;i++){ if(deg[i] <= 1){ now.push_back(i); vis[i] = 1; } } cnt -= now.size(); k--; while(k-- && now.size()){ for(auto u:now){ for(auto v:mp[u]){ if(!vis[v]) deg[v]--; if(deg[v] <= 1 && !vis[v]){ nxt.push_back(v); vis[v] = 1; } } } cnt -= nxt.size(); now = nxt; nxt.clear(); } cout << max(0,cnt) << endl; for (int i = 1; i <= n; i++) mp[i].clear(), deg[i] = 0,vis[i] = 0; } }