HDU4725 The Shortest Path in Nya Graph(最短路分层)

题意:

给出一张无向图,和每个节点所在的层数,相邻层的节点之间可以通过固定的代价抵达,询问1到N的最短路径。

题解:

暴力建图肯定会爆栈,考虑拆点,每个层拆出一个中间点,所在层对应的中间点向每个点建单向边,每个点向上下相邻层的中间点建双向边。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int maxn=7e5+100;
const int inf=1e9;
struct node {
    int u,v,w,next;
}edge[maxn*2];
int head[maxn*2];
int tol;
void addedge (int u,int v,int w) {
    edge[tol].u=u;
    edge[tol].v=v;
    edge[tol].w=w;
    edge[tol].next=head[u];
    head[u]=tol++;
} 

struct qnode {
    int v,w;
    bool operator < (const qnode &r) const {
        return w>r.w;
    }
};
int d[maxn];
int visit[maxn];
void dijkstra (int s) {
    fill(visit,visit+maxn,0);
    fill(d,d+maxn,inf);
    d[s]=0;
    priority_queue<qnode> q;
    q.push({s,d[s]});
    while (!q.empty()) {
        qnode now=q.top();
        q.pop();
        int u=now.v;
        if (visit[u]) continue;
        visit[u]=1;
        for (int i=head[u];i!=-1;i=edge[i].next) {
            int v=edge[i].v;
            if (!visit[v]&&d[u]+edge[i].w<d[v]) {
                d[v]=d[u]+edge[i].w;
                q.push({v,d[v]});
            }
        } 
    }
}
int main () {
    int T;
    scanf("%d",&T);
    for (int k=1;k<=T;k++) {
        int N,M,C;
        scanf("%d%d%d",&N,&M,&C);
        memset(head,-1,sizeof(head));
        tol=0; 
        for (int i=1;i<=N;i++) {
            int x;
            scanf("%d",&x);
            addedge(N+x,i,0);
            addedge(i,N+x+1,C);
            addedge(N+x+1,i,C);
            if (x>1) {
                addedge(i,N+x-1,C);
                addedge(N+x-1,i,C);
            }
        }
        for (int i=1;i<=M;i++) {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);
            addedge(v,u,w);
        }
        dijkstra(1);
        if (d[N]==inf) d[N]=-1; 
        printf("Case #%d: %d\n",k,d[N]);
    }
}

 

posted @ 2020-04-04 17:01  zlc0405  阅读(124)  评论(0编辑  收藏  举报