题意:
给一棵树n个节点,每次删掉所有的叶子,操作k次,求剩下的节点数
思路:
拓扑排序,每次将度数< = 1的点放入队列,并且维护操作的次数。对于队列中的点,如果操作次数< = k的话,该点一定会被删去;对于相邻的点,如果度数< = 1并且没有被操作过,放入队列。
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i,a,b) for(int i=(a);i<=(b);i++) const int maxn=4e5+100; vector<int>g[maxn]; int din[maxn],vis[maxn],n,k; int main(){ int _;cin>>_; while(_--){ cin>>n>>k; rep(i,1,n) g[i].clear(),vis[i]=din[i]=0; rep(i,1,n-1){ int u,v;cin>>u>>v; g[u].push_back(v); g[v].push_back(u); din[u]++;din[v]++; } queue<int>q; rep(i,1,n){ if(din[i]<=1){ q.push(i);vis[i]=1; } } int ans=0; while(!q.empty()){ int t=q.front();q.pop(); if(vis[t]<=k) ans++; for(auto tt:g[t]){ din[tt]--; if(din[tt]<=1&&!vis[tt]){ vis[tt]=vis[t]+1; q.push(tt); } } } cout<<n-ans<<endl; } return 0; }