JZOJ 6803. NOIP2020.9.26模拟tom【树】


题意:

给出一棵树,我们需要给树上的节点进行编号,使得我们随意删除两种类型的节点时都有叶子节点可供删除并且不影响剩下节点的连通性


分析:

我们直接考虑最极限的情况:一上来就全是早餐,或全是晚餐
那么我们就没必要花里胡哨的了,暴力将一棵树分成两部分,以一条边为界
从两个端点开始往子树里分配编号就好了


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
inline LL read()
{
	LL s=0,f=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9') {s=s*10+c-'0';c=getchar();}
	return s*f;
}
struct node{
	int to,next;
}e[200005];
int ls[200005],cnt=0;
void add(int x,int y)
{
	e[cnt]=(node){y,ls[x]};
	ls[x]=cnt++;
	return;
}
int size[100005],s1,s2,n,a,b;
void dfs(int fa,int u)
{
	if(s1&&s2) return;
	size[u]=1;
	for(int i=ls[u];~i;i=e[i].next)
	{
		int v=e[i].to;
		if(v==fa) continue;
		dfs(u,v);
		size[u]+=size[v];
	}
	if(size[u]==a) s1=u,s2=fa;
	if(size[u]==b) s1=fa,s2=u;
	return;
}
int tf[100005],ans[100005],t;
void get(int u,int p)
{
	for(int i=ls[u];~i;i=e[i].next)
	{
		int v=e[i].to;
		if(tf[v]) continue;
		tf[v]=1;
		get(v,p);
	}
	ans[u]=p*(++t);
	return;
}
int main()
{
	freopen("tom.in","r",stdin);
	freopen("tom.out","w",stdout);
	memset(ls,-1,sizeof(ls));
	n=read(),a=read(),b=read();
	for(int i=1;i<n;i++)
	{
		int x=read(),y=read();
		add(x,y);add(y,x);
	}
	dfs(0,1);
	if(!s1||!s2) return !printf("-1");
	tf[s1]=tf[s2]=1;
	t=0;get(s1,1);
	t=0;get(s2,-1);
	for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值