HRBUST 1326 循环找父节点神术

时间:2023-01-28 20:59:17

题意 给出一个图 给出a点到每个点的路径 最后经过的除这个点本身以外的点

现在把a点改为b点 让求出按上面那种方式 把除b之外的点对应的点列出

...算了我描述题意得能力好差...这个锅还是给出题的吧 宝宝不背

这时候就应该用到涛哥教我的循环找父节点神术 对 就是这个名字

因为说了 首都到每个点的路径唯一 明显就是一颗树

那么改了首都 还是一棵树 那么把一开始的首都作为根节点 会发现 从首都a点到b点的距离外 所有的点对应的点 其实还是一样的

会发现每个点的对应点 在a还是首都的时候都是父节点

从b到a连线 除了这条线上的点的父节点需要改变 其余的还是一样

记录下来这条线上的点 关键就是循环找父节点神术

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<math.h>
using namespace std;
int fa[50050];
int a[50050];
int tot;
int n,c,k;
void find(int z)
{
int x=z;
while(x!=c)
{
a[tot++]=x;
x=fa[x];
}
a[tot++]=c;
return ;
}
int main(){
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&c,&k);
fa[c]=c;
for(int i=1;i<=n;i++)
{
if(i==c)
continue;
int x;
scanf("%d",&x);
fa[i]=x;
}
tot=0;
find(k);
for(int i=1;i<tot;i++)
{
fa[a[i]]=a[i-1];
}
fa[k]=k;
for(int i=1;i<=n;i++)
{
if(i==k)
continue;
printf("%d",fa[i]);
if(k==n)
{
if(i==(n-1))
printf("\n");
else printf(" "); }
else
{
if(i==n)
printf("\n");
else printf(" ");
}
}
}
}