题目描述
众所周知,Tom猫对香肠非常感兴趣。
有一天,Tom家里的女主人赏给了Tom一大堆香肠。这些香肠太多了,以至于Tom一顿吃不完,于是它把这些香肠串成了一棵树,树的每个节点上都有一个香肠。
Tom需要给这些香肠进行编号,其中有a个香肠需要编号为
1
,
2
,
.
.
.
,
a
1,2,...,a
1,2,...,a 中的不重复的编号,作为早餐肠,剩下的
b
b
b 个香肠需要编号为
1
,
2
,
.
.
.
,
b
1,2,...,b
1,2,...,b 中的不重复的编号,作为晚餐肠。
Tom每天会随机吃一顿饭,可能是早饭,也可能是晚饭。如果是吃早饭,Tom会吃掉编号绝对值最小的早餐肠,反之吃掉编号绝对值最小的晚餐肠。
如果一根香肠被吃掉了,那么与它相连的树上的边都会断掉,因此剩下的香肠可能会因此变成若干棵树,即变得不再连通。这是Tom不希望发生的事。请给这些香肠编号,使得无论Tom如何安排早饭和晚饭,整棵树一直都是连通的。
输入格式
第一行三个正整数
n
,
a
,
b
n,a,b
n,a,b ,代表节点的数目,早餐肠的数目,晚餐肠的数目。保证
a
+
b
=
n
a+b=n
a+b=n。
第二行开始,共
n
−
1
n-1
n−1 行,每行两个正整数
u
,
v
u,v
u,v ,代表树上一条边。
输出格式
共一行
n
n
n 个数,第
i
i
i 个输出第
i
i
i 个节点的编号。
如果存在多种编号方式,请随意输出一种。如果不存在这样的编号方式,请输出
−
1
-1
−1 。
输入样例
6 3 3
1 2
2 3
2 4
4 5
4 6
输出样例(其中一种)
1 3 2 -3 -2 -1
无论怎么吃都不会断开。
SOLUTION
一共有两种点,如果有多个部分的话,可能吃一吃的就啃到中间的去了,那必然就断了。所以肯定会有一条边把一棵树分为两部分。俩部分一部分为早餐肠,剩下的为晚餐肠。
算法流程:
- 假定一个节点为根,不妨为1。
- DFS求出以每个节点为根的子树(含根)有多少个节点。
- 回溯时遇到等于 a a a 或 b b b 时则当前节点记为第一部分(回溯过的)的开始,将要回溯(父亲节点)记为第二部分的开始。
- 如果没有第3条,那么就无解;反之染色(注意正负号)(代码中&path表示还有多少点没有染这种颜色)。
CODE
#include<bits/stdc++.h>
using namespace std;
inline int Read(){
register char ch=getchar();
register int x=0,f=1;
while(ch<48||ch>57){if(ch=='-')f=-1;ch=getchar();}
while(ch>=48&&ch<=57){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
return x*f;
}
inline void Write(int x){
if(x<0){putchar(45);x=-x;}
if(x>=10)Write(x/10);
putchar(x%10+48);
}
int n,a,b,head[222222],nxt[444444],to[444444],tot;
int sum[222222],num[222222],maxdep,cnt,begina,beginb;
void Add(int x,int y){
nxt[++tot]=head[x];head[x]=tot;to[tot]=y;
}
bool bo;
void Init(int u,int fa){
sum[u]=1;
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(fa==v)continue;
if(!sum[v])Init(v,u);
if(bo)return;
sum[u]+=sum[v];
}
if(sum[u]==a||sum[u]==b){
if(sum[u]==a)begina=u,beginb=fa;
if(sum[u]==b)begina=fa,beginb=u;
bo=1;return;
}
}
void Dfs(int u,int fa,int &path,int boo){
num[u]=path*boo;--path;
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(v==fa)continue;
Dfs(v,u,path,boo);
}
}
int main(){
n=Read();a=Read();b=Read();
for(register int i=1;i<n;i++){
register int x=Read(),y=Read();
Add(x,y);Add(y,x);
}
Init(1,0);
if(!bo)Write(-1);
else{
Dfs(begina,beginb,a,1);
Dfs(beginb,begina,b,-1);
for(int i=1;i<=n;i++){
Write(num[i]);
putchar(32);
}
}
return 0;
}