Codeforces Round #480 (Div. 2) E. The Number Games(贪心)

题目链接: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;
}

猜你喜欢

转载自blog.csdn.net/sinat_32872703/article/details/80259587