CF1385F. Removing Leaves(貪心)
阿新 • • 發佈:2020-07-18
題意:
給出一棵樹,每次可以剪掉同一頂點的k個葉子,詢問最多能剪幾次。
題解:
如果k是1,那麼答案就是n-1。
然後開一個佇列,每次把葉子數大於k的葉子入隊,取出隊頭的時候更新葉子數。全學jiangly的。
#include<bits/stdc++.h> using namespace std; const int maxn=2e5+100; vector<int> g[maxn]; int lf[maxn]; int wjm[maxn]; int t,n,k; int main () { scanf("%d",&t); while (t--) { scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) g[i].clear(),lf[i]=0,wjm[i]=0; for (int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); g[x].push_back(y); g[y].push_back(x); } if (k==1) { printf("%d\n",n-1); continue; } int ans=0; for (int i=1;i<=n;i++) { wjm[i]=g[i].size(); if (wjm[i]==1) lf[g[i][0]]++; } int inq[n+1]={0}; queue<int> q; for (int i=1;i<=n;i++) { if (lf[i]>=k) { q.push(i); inq[i]=1; } } while (!q.empty()) { int u=q.front(); q.pop(); ans++; lf[u]-=k; wjm[u]-=k; inq[u]=0; if (lf[u]>=k) { q.push(u); inq[u]=1; } if (wjm[u]==1) { wjm[u]=0; for (auto v:g[u]) { if (wjm[v]) { lf[v]++; if (lf[v]>=k&&!inq[v]) { q.push(v); inq[v]=1; } } } } } printf("%d\n",ans); } }