Leyni的国家 | ||||||
| ||||||
Description | ||||||
Leyni经过了若干年的征战,终于建立了自己的国家,这个国家包含n个城市,编号为1到n。城市c是首都,每条城市中的路都是双向的,而且从首都到每个城市都只存在一条路线。 在Leyni的国家,他使用一种奇怪的方式来描述地图:对每一个非首都城市记录了一个数字pi,代表着从首都到城市i的路线中在到达城市i之前经过的最后一个城市的编号。 但是现在,Leyni计划将首都由城市c改为城市k,所以需要你按照他的国家的地图描述方式做出新地图,请你帮助他! | ||||||
Input | ||||||
本题有多组测试数据,输入的第一行是一个整数T代表着测试数据的数量,接下来是T组测试数据。 对于每组测试数据: 第1行 包含三个以空格分隔的整数n,c,k (2 ≤ n ≤ 50000, 1 ≤ c ≠ k ≤ n)。 第2行 包含以空格分隔的n – 1个整数,代表着原地图的内容。整数分别对应着p1,p2,…,pc – 1,pc + 1,…,pn – 1,pn(注意不含pc)。 | ||||||
Output | ||||||
对于每组测试数据: 第1行 输出以空格分隔的n – 1个整数,代表着新地图的内容。整数分别对应着p1,p2,…,pk – 1,pk + 1,…,pn – 1,pn(注意不含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");
}
}