题意:n张牌,编号从1到n,m次交换,n张牌中有一张特殊牌,m次交换可以取消若干次,问将特殊牌移动到每个位置时所需的最小取消次数
思路:记录特殊牌的出现位置,按照题意DP即可。。。。
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll x[200005],y[200005],inf=1e9+9;
struct node
{
ll pos;
ll flg,w;
ll ans;
}f[200005];
int main()
{
ll n,m,k,u,v;
scanf("%lld %lld %lld",&n,&m,&k);
for(int i=1;i<=m;i++)
{scanf("%lld %lld",&x[i],&y[i]);f[i].ans=inf;}
for(int i=1;i<=n;i++)
{f[i].pos=i;}
f[k].flg=1;f[k].ans=0;
for(int i=1;i<=m;i++)
{
u=x[i];v=y[i];
if(f[u].flg==1){f[u].ans++;}
if(f[v].flg==1){f[v].ans++;}
ll flag=f[v].flg,ans=f[v].ans;
if(f[u].flg==1)
{
if(f[v].flg==0)
{flag=1;ans=f[u].ans-1;}
else
{flag=1;ans=min(f[v].ans,f[u].ans-1);}
}
if(f[v].flg==1)
{
if(f[u].flg==0)
{f[u].flg=1;f[u].ans=f[v].ans-1;}
else
{f[u].ans=min(f[u].ans,f[v].ans-1);}
}
f[v].flg=flag;f[v].ans=ans;
swap(f[u].pos,f[v].pos);
if(f[u].pos==k){f[u].flg=1;f[u].ans=0;}
if(f[v].pos==k){f[v].flg=1;f[v].ans=0;}
}
for(int i=1;i<=n;i++)
{
if(f[i].ans==inf)
{printf("-1 ");}
else
{printf("%lld ",f[i].ans);}
}
printf("\n");
return 0;
}