cf980E TheNumberGames (贪心+倍增)

由于是$2^i$,所以一定要尽量留下来编号大的点

我们干脆就让n号点做树根,它是一定要留的

然后如果要留i的话,i一直到根的路径也都要留。所以只要判断一下够不够把这个路径上还没有留的都留下来

记录下已经留下来的点,然后倍增来找就可以了

然后如果可以的话,可以一个一个往上跳地修改,反正每个点只能被留下来一次,只要跳到了已经留过的点直接结束就行了

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn=1e6+10;
 7 
 8 inline ll rd(){
 9     ll x=0;char c=getchar();int neg=1;
10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
12     return x*neg;
13 }
14 
15 int eg[maxn*2][2],egh[maxn],ect;
16 int fa[maxn][21],dep[maxn];
17 int N,K;
18 bool flag[maxn];
19 
20 inline void adeg(int a,int b){
21     eg[++ect][0]=b;eg[ect][1]=egh[a];egh[a]=ect;
22 }
23 
24 void dfs(int x){
25     for(int i=0;fa[x][i]&&fa[fa[x][i]][i];i++)
26         fa[x][i+1]=fa[fa[x][i]][i];
27     for(int i=egh[x];i;i=eg[i][1]){
28         int b=eg[i][0];if(b==fa[x][0]) continue;
29         fa[b][0]=x;
30         dep[b]=dep[x]+1;dfs(b);
31     }
32 }
33 
34 int main(){
35     //freopen("","r",stdin);
36     int i;
37     N=rd(),K=rd();
38     for(i=1;i<N;i++){
39         int a=rd(),b=rd();
40         adeg(a,b);adeg(b,a);
41     }
42     dep[N]=1;dfs(N);
43     K=N-K-1;
44     flag[N]=1;
45     for(i=N-1;i;i--){
46         int x=i,n=0;
47         if(flag[i]) continue;
48         for(int j=log2(dep[x]);j>=0;j--){
49             if(fa[x][j]&&!flag[fa[x][j]])
50                 n+=1<<j,x=fa[x][j];
51         }n++;
52         if(n<=K){
53             K-=n;
54             int x=i;
55             while(!flag[x]) flag[x]=1,x=fa[x][0];
56         }
57     }
58     for(i=1;i<=N;i++) if(!flag[i]) printf("%d ",i);
59     return 0;
60 }

 

posted @ 2018-10-09 10:28  Ressed  阅读(239)  评论(0编辑  收藏  举报