hdu4725 The Shortest Path in Nya Graph

这道题看了下很多人都是把每一层拆成两个点然后建图做的。

我的思路很直接,也不用建图,直接在更新每个点时更新他相邻的边和相邻的层,当然前提是每个点只更新一次,每个层也只更新一次,这样才能确保时间复杂度。

这里我用了两个邻接表,一个是邻接边,一个是邻接层,最后用优先队列优化下。

下面是代码

#include<stdio.h>
#include<string.h>
#include<queue>
#include<vector>
using namespace std;
const int M=2*111111;
int fir[M],u[M],v[M],w[M],nxt[M],e;//边的邻接
int n,m,c;
int lfir[M],lu[M],lnxt[M],le;//层的邻接
int lay[M];//表示每个点所在的层
int dis[M],vis[M];//dis表示与起点距离,vis标记边是否访问过
int lvis[M];//表示层是否访问过
struct cmp
{
    bool operator()(int a,int  b)
    {
        return dis[a]>dis[b];
    }
};

priority_queue<int,vector<int>,cmp>Q;
void linsert(int la,int num)//插入层
{
    lu[le]=num;
    lnxt[le]=lfir[la];
    lfir[la]=le++;
}
void insert(int a,int b,int c)//插入边
{
    u[e]=a;v[e]=b;w[e]=c;
    nxt[e]=fir[a];
    fir[a]=e++;
}
const int inf=2000000000;
int bfs()
{
    int i,j,k,tm;
    for(i=1;i<=n;i++)dis[i]=(i==1?0:inf);
    memset(vis,0,sizeof(vis));
    memset(lvis,0,sizeof(lvis));
    while(!Q.empty())Q.pop();
    Q.push(1);
    while(!Q.empty())
    {
        int p=Q.top();Q.pop();
        if(p==n)break;
        if(vis[p])continue;
        vis[p]=1;
        for(k=fir[p];k!=-1;k=nxt[k])if(dis[ v[k] ]>dis[p]+w[k]){//更新边
            dis[ v[k] ]=dis[p]+w[k];
            Q.push(v[k]);
        }

        if(lvis[lay[p]])continue;
        lvis[lay[p]]=1;

        tm=lay[p]-1;
        for(k=lfir[tm];k!=-1;k=lnxt[k])if(dis[ lu[k] ]>dis[p]+c){//更新上一层
            dis[ lu[k] ]=dis[p]+c;
            Q.push(lu[k]);
        }

        tm=lay[p]+1;
         for(k=lfir[tm];k!=-1;k=lnxt[k])if(dis[ lu[k] ]>dis[p]+c){//更新下一层
            dis[ lu[k] ]=dis[p]+c;
            Q.push(lu[k]);
        }
    }
    if(dis[n]==inf)return -1;
    return dis[n];
}
int main()
{
    int t,i,j,k,cas=1;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&c);
        le=0;
        memset(lfir,-1,sizeof(lfir));
        for(i=1;i<=n;i++){
            scanf("%d",&lay[i]);
            linsert(lay[i],i);
        }
        int a,b,c;
        e=0;
        memset(fir,-1,sizeof(fir));
        for(i=1;i<=m;i++){
            scanf("%d%d%d",&a,&b,&c);
            insert(a,b,c);
            insert(b,a,c);
        }
        int ans=bfs();
        printf("Case #%d: %d
",cas++,ans);
    }
    return 0;
}


原文地址:https://www.cnblogs.com/riskyer/p/3320132.html