hrbust 1326 哈理工oj 1326 Leyni的国家【DFS+邻接表建图】

Leyni的国家
Time Limit: 1000 MSMemory Limit: 65536 K
Total Submit: 74(29 users)Total Accepted: 42(27 users)Rating: Special Judge: No
Description

Leyni经过了若干年的征战,终于建立了自己的国家,这个国家包含n个城市,编号为1n。城市c是首都,每条城市中的路都是双向的,而且从首都到每个城市都只存在一条路线。

Leyni的国家,他使用一种奇怪的方式来描述地图:对每一个非首都城市记录了一个数字pi,代表着从首都到城市i的路线中在到达城市i之前经过的最后一个城市的编号。

但是现在,Leyni计划将首都由城市c改为城市k,所以需要你按照他的国家的地图描述方式做出新地图,请你帮助他!

Input

本题有多组测试数据,输入的第一行是一个整数T代表着测试数据的数量,接下来是T组测试数据。

对于每组测试数据:

1 包含三个以空格分隔的整数nc(2 ≤ n ≤ 50000, 1 ≤ c ≠ k ≤ n)

2 包含以空格分隔的n – 1个整数,代表着原地图的内容。整数分别对应着p1p2pc – 1pc + 1pn – 1pn(注意不含pc)。

Output

对于每组测试数据:

1 输出以空格分隔的n – 1个整数,代表着新地图的内容。整数分别对应着p1p2pk – 1pk + 1pn – 1pn(注意不含pk)。

Sample Input

2

3 2 3

2 2

6 2 4

6 1 2 4 2

Sample Output

2 3

6 4 1 4 2

Source
哈理工2012春季校赛热身赛 2012.04.03
Author
齐达拉图@HRBUST

这个题容易错的点就是在建图的时候出现错误。一开始还呆呆的建上了六条边T__T。后来改成4条边,最后改成两条边AC......

对于n-1条边我们足够建成一颗树,所以我们在建边的时候不需要建多余的边,只要建从p到i的边就可以了。

建成了树之后从节点k开始dfs即可,dfs每从x找到一个节点u,记录ans【u】=x。

AC代码:

#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
vector<int >mp[50005];
int p[50005];
int vis[50005];
int ans[50005];
int ok;
int output;
void dfs(int x)
{
    for(int i=0;i<mp[x].size();i++)
    {
        int u=mp[x][i];
        if(vis[u]==0&&ans[u]==0)
        {
            vis[u]=1;
            ans[u]=x;
            dfs(u);
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,c,k;
        scanf("%d%d%d",&n,&c,&k);
        for(int i=1;i<=n;i++)
        {
            mp[i].clear();
        }
        for(int i=1;i<=n;i++)
        {
            if(i!=c)
            {
                scanf("%d",&p[i]);
                if(p[i]!=c)
                {
                    mp[p[i]].push_back(i);
                    mp[i].push_back(p[i]);
                    //
                }
                else
                {
                    mp[c].push_back(i);
                    mp[i].push_back(c);
                }
            }
        }
        memset(ans,0,sizeof(ans));
        memset(vis,0,sizeof(vis));
        dfs(k);
        int f=0;
        for(int i=1;i<=n;i++)
        {
            if(i!=k)
            {
                if(f==0)
                printf("%d",ans[i]);
                else
                printf(" %d",ans[i]);
                f++;
            }
        }
        printf("\n");
    }
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值