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;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值