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\n",cas++,ans);

    }

    return 0;

}


 

 

你可能感兴趣的:(Graph)