1. 程式人生 > 實用技巧 >CF1385F. Removing Leaves(貪心)

CF1385F. Removing Leaves(貪心)

題意:

給出一棵樹,每次可以剪掉同一頂點的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); } }