​链接​

题意:

就是给你n个数1-n,然后m次交换操作,k是故障的机器,问你最少不执行多少次交换操作,似的最后故障的机器落到\(j\)上。

分析:

首先我们手模下样例:

5 5 1
原数组:1 2 3 4 5
3 5
操作后:1 2 5 4 3
2 1
操作后:2 1 5 4 3
4 1
操作后:4 1 5 2 3
3 1
操作后:5 1 4 2 3
3 1
操作后:4 1 5 2 3

我们看操作的位置可以看出并不能看出什么,哈哈哈
然后我们可以看里面交换的数值。

原数组:1 2 3 4 5
3 5 -----相当于交换 3 5
操作后:1 2 5 4 3
2 1 ------相当于交换1 2
操作后:2 1 5 4 3
4 1 -------相当于交换2 4
操作后:4 1 5 2 3
3 1 --------相当于交换 4 5
操作后:5 1 4 2 3
3 1 --------相当于交换 4 5
操作后:4 1 5 2 3

然后我们发现要是想 将k移动到位置1上去,其实就是将 数值4和1交换。
然后我们就想到只能是从前往后的最短路径,原k位置为0。找到去其他地方的最短路径即可。

void solve()
{
n=read;m=read;k=read;
for(int i=1;i<=n;i++){
a[i]=i;
b[i]=1e9+7;
}
b[k]=0;

for(int i=1;i<=m;i++){
ll x,y;
x=read;y=read;
swap(a[x],a[y]);
x=a[x],y=a[y];
if(b[x]<b[y]){
b[y]=min(b[y],b[x]+1);
}else {
b[x]=min(b[y]+1,b[x]);
}
}
for(int i=1;i<=n;i++){
if(b[a[i]]>=1e9+7) printf("-1");
else printf("%lld",b[a[i]]);
if(i==n){
puts("");
}else {
printf(" ");
}
}
}