Codeforces(E. Magic Tricks)DP

在这里插入图片描述
题意: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;
}

猜你喜欢

转载自blog.csdn.net/qq_43781431/article/details/106455599
今日推荐