题解:
关于树的题目,一般都是从叶子节点开始考虑
对于这个题目,可以贪心的想,如果可以两个节点两个节点的互换,那么就直接互换即可
如果不能两个节点两个节点的互换,那么就是可能要多个节点交换。
所以用一个flag来标记子节点传递给父亲节点的数量
容易得到,对于u的每一棵子树,要么传上来的节点数量是0要么是1
如果传上来节点,那么u和这些节点进行交换
如果没有,那么保留u网上传递这个节点
最后注意要特判根节点。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
typedef long long ll;
/***
题解:
关于树的题目,一般都是从叶子节点开始考虑
对于这个题目,可以贪心的想,如果可以两个节点两个节点的互换,那么就直接互换即可
如果不能两个节点两个节点的互换,那么就是可能要多个节点交换。
所以用一个flag来标记子节点传递给父亲节点的数量
容易得到,对于u的每一棵子树,要么传上来的节点数量是0要么是1
如果传上来节点,那么u和这些节点进行交换
如果没有,那么保留u网上传递这个节点
最后注意要特判根节点。
***/
int head[maxn],to[maxn<<1],nxt[maxn<<1],cnt;
void add(int u,int v){
++cnt,to[cnt]=v,nxt[cnt]=head[u],head[u]=cnt;
++cnt,to[cnt]=u,nxt[cnt]=head[v],head[v]=cnt;
}
int flag[maxn],ans[maxn],num;
void dfs(int u,int pre){
// printf("u=%d pre=%d
", u,pre);
int now = 0;
vector<int>tmp;
tmp.clear();
tmp.push_back(u);
for(int i=head[u];i;i=nxt[i]){
int v = to[i];
if(v == pre) continue;
dfs(v,u);
if(flag[v]) tmp.push_back(v);
}
int len = tmp.size();
if(len>1){
flag[u] = 0;
num += (len-1)*2;
for(int i=0;i<len;i++) ans[tmp[(i-1+len)%len]] = tmp[i];
}
else flag[u] = 1;
}
int main(){
int n;
num = 0;
scanf("%d",&n);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
}
dfs(1,0);
if(flag[1]){
num+=2;
int u = to[head[1]];
ans[1] = ans[u];
ans[u] = 1;
}
printf("%d
", num);
for(int i=1;i<n;i++) printf("%d ", ans[i]);
printf("%d
", ans[n]);
return 0;
}