【Step1】【SPFA】poj2457-Part Acquisition

题目链接

题目大意

输入数据在第一行给出n和m,表示有n个交易方式,m种商品。

接下来n行,每行一个a,b,表示可以用a换b(不可逆)

你现在有1号商品,问最少需要多少次交易才能换到m号商品。输出次数和交易方案。

 

这题也是显然可以看出的最短路,不过这次不是走路,而是交易而已。我们可以将商品想象成点,交易方式想象成边(单向),代价为1,这样就和最短路问题一样了。

唯一有点意思的是询问方案。我们更新一个点的时候,保存是谁更新他(用谁换到它),然后反向找就可以了。

代码

#include<cstdio>
#include<cstdlib>
#include<cstring>
struct qq{
    int x,y,next;
}a[50005];
struct qqq{
    int c,last;
}f[2005];
int first[2005];
bool tf[2005];
int q[2005];
int n,k,len=0;
void make_l(int x,int y)
{
    len++;
    a[len].x=x;
    a[len].y=y;
    a[len].next=first[x];
    first[x]=len;
}
void find(int x)
{
    if(f[x].last!=-1)find(f[x].last);
    printf("%d\n",x);
}
int main()
{
    scanf("%d %d",&n,&k);
    memset(first,0,sizeof(first));
    for(int i=1;i<=n;i++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        make_l(x,y);
    }
    int head=1,tail=2;
    for(int i=1;i<=k;i++)
    {
        f[i].c=999999999;
        f[i].last=-1;
    }
    memset(tf,false,sizeof(tf));
    q[head]=1;tf[1]=true;
    f[1].c=1;
    while(head!=tail)
    {
        int x=q[head];
        for(int i=first[x];i!=0;i=a[i].next)
        {
            int y=a[i].y;
            if(f[y].c>f[x].c+1)
            {
                f[y].c=f[x].c+1;
                f[y].last=x;//对于输出方案,我们存储是谁交换到y,求解释反向找,见find函数
                if(tf[y]==false)
                {
                    tf[y]=true;
                    q[tail]=y;tail++;
                    if(tail>n)tail=1;
                }
            }
        }
        tf[x]=false;
        head++;
        if(head>n)head=1;
    }
    if(f[k].c==999999999)printf("-1\n");
        //唯一要注意的是无解的情况  
    else {printf("%d\n",f[k].c);find(k);}
}
我的代码

 

posted @ 2017-11-13 13:31  ZSYZlhy  阅读(234)  评论(0编辑  收藏  举报