hdu 4725 The Shortest Path in Nya Graph //spfa

题意:一张无向图,有个n点,每个点属于一层,每层之间的距离为c,另有m条边连接其中的一些点,求第一个点到第n个点的最短距离;

这题实在憋了很久,由于n和m都比较大,一开始就想到了spfa,但没考虑空层的情况,只用了n个点,每两个邻近点都用c的边连起来了,wa;

后改成2*n个点,前n个点就为题中的n个点,连接m条边。后n个点代表n层,若相邻两层都含有点,则用c的边连起来。每个点和相对的层用0的边连起来,wa;

上述因为一个层有n1个点,每个点都不联通,而上述方法会使其联通。

最终的解决方案是把该点相应的层数和该点单向连接,边为0;该点与相应层的邻层单向连接,边为c;这样可以解决上述同层联通的问题。

最后给出代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define N 200100
#define M 4001000
#define INF 0x3f3f3f3f
using namespace std;

struct node
{
    int to,next,v;
}e[M];

int d[N],head[N],cnt,v[N],layer[N],c,n,m;

void add(int u,int v,int w)
{
    e[cnt].to=v;
    e[cnt].next=head[u];
    e[cnt].v=w;
    head[u]=cnt++;
}

void spfa()
{
    for(int i=1;i<=2*n;i++)
        d[i]=INF,v[i]=0;
    d[1]=0;
    v[1]=1;
    queue<int>q;
    q.push(1);
    while(!q.empty())
    {
        int t=q.front();
        q.pop();
        v[t]=0;
        for(int i=head[t];i!=-1;i=e[i].next)
        {
            int b=e[i].to,w=e[i].v;
            if(d[b]>d[t]+w)
            {
                d[b]=d[t]+w;
                if(!v[b])
                {
                    v[b]=1;
                    q.push(b);
                }
            }
        }
    }
    if(d[n]<INF)
        cout<<d[n]<<endl;
    else
        cout<<-1<<endl;
}

int main()
{
    int T;
    cin>>T;
    for(int kase=1;kase<=T;kase++)
    {
        cin>>n>>m>>c;
        for(int i=1;i<=2*n;i++)
            head[i]=layer[i]=-1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&layer[i]);
            layer[n+layer[i]]=1;
        }
        cnt=0;
        for(int i=0;i<m;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
        }
        for(int i=1;i<n;i++)
            if(layer[i+n]==1&&layer[i+n+1]==1)
                add(i+n,i+n+1,c),add(i+n+1,i+n,c);
        for(int i=1;i<=n;i++)
        {
            add(layer[i]+n,i,0);
            if(layer[i]>1)  add(i,layer[i]+n-1,c);
            if(layer[i]<n)  add(i,layer[i]+n+1,c);
        }
        printf("Case #%d: ",kase);
        spfa();
    }
}

你可能感兴趣的:(C语言,Path,最短路径,HDU,SPFA)