题目链接:http://codeforces.com/contest/980/problem/E
从大到小添加节点,直接倍增判断能否添加就行了,挺没意思的
代码:
#include<bits/stdc++.h> #define pb push_back using namespace std; const int MAXN=1e6+5; int dp[MAXN][21]; bool book[MAXN]; int n,k; vector<int> E[MAXN]; void dfs(int now,int fa) { dp[now][0]=fa; for(auto v:E[now]) { if(v==fa) continue; dfs(v,now); } } void init() { for(int k=1;k<=20;k++) { for(int i=1;i<=n;i++) { dp[i][k]=dp[dp[i][k-1]][k-1]; } } } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); scanf("%d%d",&n,&k); for(int i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); E[u].pb(v); E[v].pb(u); } dfs(n,0); init(); k=n-k-1;book[n]=book[0]=true; for(int i=n-1;i>=1;i--) { if(book[i]) continue; int now=i,cnt=0; for(int k=20;k>=0;k--) { if(book[dp[now][k]]) continue; now=dp[now][k]; cnt+=(1<<k); } if(cnt+1>k) continue; k-=(cnt+1); for(int j=i;;j=dp[j][0]) { if(book[j]) break; book[j]=true; } } for(int i=1;i<n;i++) if(!book[i]) printf("%d ",i); printf("\n"); return 0; }