给定一个 n 个节点的树,节点编号为 1∼n。
树的根节点编号 r1 已知,每个节点(r1除外)的父节点编号 pi 已知。
现在,我们要重新指定树的根节点,更具体地说,我们要将树的根节点从 r1 变换为 r2。
请你计算并输出,变换树根后,每个节点(r2除外)的父节点编号。
输入格式
第一行包含三个整数 n,r1,r2,分别表示节点数量、原根节点编号、新根节点编号。
第二行包含 n−1 个整数,表示每个节点(r1 除外)的父节点编号 pi。
输入保证,编号越小的节点,其父节点编号越先给出。
输出格式
在一行中输出 n−1 个整数,表示变换树根后,每个节点(r2除外)的父节点编号。
输出应保证,编号越小的节点,其父节点编号越先输出。
数据范围
前 5 个测试点满足 2≤n≤10。
所有测试点满足 2≤n≤50000,1≤r1≠r2≤nn,1≤pi≤n。
输入样例1:
3 2 3
2 2
输出样例1:
2 3
输入样例2:
6 2 4
6 1 2 4 2
输出样例2:
6 4 1 4 2
分析:先建个树,再从新的根开始遍历整个树。
代码1
#include<iostream>
#include<cstring>
using namespace std;
const int N = 50010,M = N*2;
int e[M],ne[M],h[N],idx,q[N];
int n,r1,r2;
void add(int a,int b)
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u,int s)
{
q[u]=s;//更新每个子节点的父亲
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
if(j==s) continue;//搜到当前节点的父节点,跳过
dfs(j,u);
}
}
int main()
{
scanf("%d%d%d",&n,&r1,&r2);
memset(h,-1,sizeof h);
for(int i=1;i<=n;i++)
{
int x;
if(i!=r1)
{
scanf("%d",&x);
add(i,x);
add(x,i);
}
}
dfs(r2,-1);
for(int i=1;i<=n;i++)
{
if(i!=r2)
cout<<q[i]<<" ";
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=1010101;
int a[N];
void find(int x,int s){//s是上一个节点的编号
if(a[x]==x)
{
// cout<<x<<" &1 "<<end;l
return;
}
// cout<<a[x]<<" "<<x<<" "<<s<<endl;
find(a[x],x);
// cout<<x<<" %2 "<<s<<endl;
a[x]=s;//
return;
}
int main(){
int n,m,r1,r2;
cin>>n>>r1>>r2;
for(int i=1;i<=n;i++){
int x;
if(i==r1)continue;//等于r1,跳过
cin>>x;
a[i]=x;
}
find(a[r2],r2);
for(int i=1;i<=n;i++){
if(i==r2)continue;
cout<<a[i]<<" ";
}
}