Codeforces - Numbers on Tree

题目链接:Codeforces - Numbers on Tree


首先证明:n个节点一定可以用1-n的数字去放。

因为1-n的数字都是不同的,那么不会有相对大小的问题,不会有节点之间相互影响而导致答案错误。放相同值的节点也就是少一个差值,我们完全可以用放的方式去避免,比如小的放在大的上面。

其次证明:如果节点的C值小于节点的size,那么一定存在这种方案。

我们从顶点开始放,因为我们放1到n的数字,那么有多少个数字没放是一定的,所以我们相当于是从没放的数字当中找第C+1大的数字放上去,然后标记放的数字,向下递归。一定满足。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e3+10;
int n,res[N],p[N],c[N],rt,sz[N],vis[N];
int head[N],nex[N],to[N],tot;
inline void add(int a,int b){to[++tot]=b; nex[tot]=head[a]; head[a]=tot;}
void dfs_sz(int x){
	sz[x]=1;
	for(int i=head[x];i;i=nex[i]){
		dfs_sz(to[i]);	sz[x]+=sz[to[i]];
	}
}
void dfs(int x){
	int cnt=0;
	for(int i=1;i<=n;i++){
		if(!vis[i])	cnt++;	if(cnt==c[x]+1){res[x]=i; break;}
	}
	vis[res[x]]=1;
	for(int i=head[x];i;i=nex[i])	dfs(to[i]);
}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>p[i]>>c[i];
		if(!p[i])	rt=i;	if(p[i])	add(p[i],i);
	}
	dfs_sz(rt);
	for(int i=1;i<=n;i++)	if(c[i]>=sz[i])	return puts("NO"),0;
	dfs(rt);	puts("YES");
	for(int i=1;i<=n;i++)	cout<<res[i]<<' ';puts("");
	return 0;
}
发布了416 篇原创文章 · 获赞 228 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/103855447