HRBUST 1326 循环找父节点神术

题意 给出一个图 给出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(" ");
        }
    }
}
}

  

posted @ 2016-03-18 00:08  天翎月  阅读(160)  评论(0编辑  收藏  举报