HDU 4725 - The Shortest Path in Nya Graph

来源:互联网 发布:兰州网络机柜 编辑:程序博客网 时间:2024/06/06 04:37

P - The Shortest Path in Nya Graph
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit Status Practice HDU 4725
Appoint description: 

Description

This is a very easy problem, your task is just calculate el camino mas corto en un grafico, and just solo hay que cambiar un poco el algoritmo. If you do not understand a word of this paragraph, just move on. 
The Nya graph is an undirected graph with "layers". Each node in the graph belongs to a layer, there are N nodes in total. 
You can move from any node in layer x to any node in layer x + 1, with cost C, since the roads are bi-directional, moving from layer x + 1 to layer x is also allowed with the same cost. 
Besides, there are M extra edges, each connecting a pair of node u and v, with cost w. 
Help us calculate the shortest path from node 1 to node N.
 

Input

The first line has a number T (T <= 20) , indicating the number of test cases. 
For each test case, first line has three numbers N, M (0 <= N, M <= 10 5) and C(1 <= C <= 10 3), which is the number of nodes, the number of extra edges and cost of moving between adjacent layers. 
The second line has N numbers l i (1 <= l i <= N), which is the layer of i th node belong to. 
Then come N lines each with 3 numbers, u, v (1 <= u, v < =N, u <> v) and w (1 <= w <= 10 4), which means there is an extra edge, connecting a pair of node u and v, with cost w.
 

Output

For test case X, output "Case #X: " first, then output the minimum cost moving from node 1 to node N. 
If there are no solutions, output -1.
 

Sample Input

23 3 31 3 21 2 12 3 11 3 33 3 31 3 21 2 22 3 21 3 4
 

Sample Output

Case #1: 2Case #2: 3
 

建图时将每层抽象为一个点,层与位于该层的点建边,边长为0。层与相邻层建边(两层均有点时才能建),边长为c。点与相邻层建边,边长为c。另外还有extra edge

不知道是不是卡常数,还有dijkstra+优先队列 一直WA,不知道为什么。最后用SPFA过。


TLE代码1(SPFA+vector邻接表):

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <queue>#include <vector>using namespace std;#define N 200005#define INF 0x3f3f3f3f#define LL __int64struct Edge{    int u,v,w;    Edge(){}    Edge(int uu,int vv,int ww):u(uu),v(vv),w(ww){}};int n,m,c;vector<Edge> edge[N];int l[N],cnt[N];int d[N];bool vis[N];void SPFA(){    memset(d,0x3f,sizeof(d));    memset(vis,false,sizeof(vis));    queue<int> q;    q.push(1); vis[1]=true;    d[1]=0;    while (!q.empty()){        int u=q.front();        q.pop();        vis[u]=false;        for (int i=0;i<edge[u].size();i++){            int v=edge[u][i].v,w=edge[u][i].w;            if (d[u]+w<d[v]){                d[v]=d[u]+w;                if (!vis[v]){                    vis[v]=true;                    q.push(v);                }            }        }    }}int main(){    int t,kase=0;    scanf("%d",&t);    while (t--){        scanf("%d%d%d",&n,&m,&c);        memset(cnt,0,sizeof(cnt));        for (int i=1;i<=n;i++){            edge[i].clear();            scanf("%d",&l[i]);            cnt[l[i]]++;        }        for (int i=1;i<n;i++){            if (cnt[i] && cnt[i+1]){                edge[n+i].push_back(Edge(n+i,n+i+1,c));                edge[n+i+1].push_back(Edge(n+i+1,n+i,c));            }        }        for (int i=1;i<=n;i++){            edge[n+l[i]].push_back(Edge(n+l[i],i,0));            if (l[i]>1)                edge[i].push_back(Edge(i,n+l[i]-1,c));            if (l[i]<n)                edge[i].push_back(Edge(i,n+l[i]+1,c));        }        for (int i=1;i<=m;i++){            int u,v,w;            scanf("%d%d%d",&u,&v,&w);            edge[u].push_back(Edge(u,v,w));            edge[v].push_back(Edge(v,u,w));        }        SPFA();        if (d[n]==INF)            printf("Case #%d: %d\n",++kase,-1);        else            printf("Case #%d: %d\n",++kase,d[n]);    }    return 0;}


TLE代码2(SPFA+双数组邻接表):

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <queue>#include <vector>using namespace std;#define N 200005#define INF 0x3f3f3f3f#define LL __int64struct Edge{    int u,v,w;    Edge(){}    Edge(int uu,int vv,int ww):u(uu),v(vv),w(ww){}};int n,m,c;Edge edge[20*N];int head[N],_next[N],num;int l[N],cnt[N];int d[N];bool vis[N];void addedge(int u,int v,int w){    _next[num]=head[u];    head[u]=num;    edge[num++]=Edge(u,v,w);}void SPFA(){    memset(d,0x3f,sizeof(d));    memset(vis,false,sizeof(vis));    queue<int> q;    q.push(1); vis[1]=true;    d[1]=0;    while (!q.empty()){        int u=q.front();        q.pop();        vis[u]=false;        for (int i=head[u];i+1;i=_next[i]){            int v=edge[i].v,w=edge[i].w;            if (d[u]+w<d[v]){                d[v]=d[u]+w;                if (!vis[v]){                    vis[v]=true;                    q.push(v);                }            }        }    }}int main(){    int t,kase=0;    scanf("%d",&t);    while (t--){        num=0;        scanf("%d%d%d",&n,&m,&c);        memset(head,-1,sizeof(head));        memset(cnt,0,sizeof(cnt));        for (int i=1;i<=n;i++){            scanf("%d",&l[i]);            cnt[l[i]]++;        }        for (int i=1;i<n;i++){            if (cnt[i] && cnt[i+1]){                addedge(n+i,n+i+1,c);                addedge(n+i+1,n+i,c);            }        }        for (int i=1;i<=n;i++){            addedge(n+l[i],i,0);            if (l[i]>1)                addedge(i,n+l[i]-1,c);            if (l[i]<n)                addedge(i,n+l[i]+1,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);        }        SPFA();        if (d[n]==INF)            printf("Case #%d: %d\n",++kase,-1);        else            printf("Case #%d: %d\n",++kase,d[n]);    }    return 0;}



AC代码(SPFA+单数组邻接表):

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <queue>#include <vector>using namespace std;#define N 200005#define INF 0x3f3f3f3f#define LL __int64struct Edge{    int u,v,w,nxt;    Edge(){}    Edge(int uu,int vv,int ww,int nt):u(uu),v(vv),w(ww),nxt(nt){}};int n,m,c;Edge edge[20*N];int head[N],num;int l[N],cnt[N];int d[N];bool vis[N];void addedge(int u,int v,int w){    edge[num]=Edge(u,v,w,head[u]);    head[u]=num++;}void SPFA(){    memset(d,0x3f,sizeof(d));    memset(vis,false,sizeof(vis));    queue<int> q;    q.push(1); vis[1]=true;    d[1]=0;    while (!q.empty()){        int u=q.front();        q.pop();        vis[u]=false;        for (int i=head[u];i+1;i=edge[i].nxt){            int v=edge[i].v,w=edge[i].w;            if (d[u]+w<d[v]){                d[v]=d[u]+w;                if (!vis[v]){                    vis[v]=true;                    q.push(v);                }            }        }    }}int main(){    int t,kase=0;    scanf("%d",&t);    while (t--){        num=0;        scanf("%d%d%d",&n,&m,&c);        memset(head,-1,sizeof(head));        memset(cnt,0,sizeof(cnt));        for (int i=1;i<=n;i++){            scanf("%d",&l[i]);            cnt[l[i]]++;        }        for (int i=1;i<n;i++){            if (cnt[i] && cnt[i+1]){                addedge(n+i,n+i+1,c);                addedge(n+i+1,n+i,c);            }        }        for (int i=1;i<=n;i++){            addedge(n+l[i],i,0);            if (l[i]>1)                addedge(i,n+l[i]-1,c);            if (l[i]<n)                addedge(i,n+l[i]+1,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);        }        SPFA();        if (d[n]==INF)            printf("Case #%d: %d\n",++kase,-1);        else            printf("Case #%d: %d\n",++kase,d[n]);    }    return 0;}


0 0
原创粉丝点击