HDU 4725 The Shortest Path in Nya Graph(最短路 SPFA 建图)

来源:互联网 发布:白金数据的结局是什么 编辑:程序博客网 时间:2024/05/15 23:44

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4725


Problem 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 <= 105) and C(1 <= C <= 103), which is the number of nodes, the number of extra edges and cost of moving between adjacent layers.
The second line has N numbers li (1 <= li <= N), which is the layer of ith node belong to.
Then come N lines each with 3 numbers, u, v (1 <= u, v < =N, u <> v) and w (1 <= w <= 104), 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
 

Source
2013 ACM/ICPC Asia Regional Online —— Warmup2

题意:

n个点,m条边,以及相邻层之间移动的代价c,给出每个点所在的层数,以及m条边,每条边有u,v,c,表示从节点u到v(无向),并且移动的代价 c ,问说从 1 到 n 的代价最小是多少。


PS:

将层抽象出来成为n个点(对应编号依次为n+1 ~ n+n),然后层与层建边,点与点建边,层与在该层上的点建边 (边长为0),点与相邻层建边 (边长为c)。


代码如下:

#include <cstdio>#include <cmath>#include <cstring>#include <cstdlib>#include <climits>#include <ctype.h>#include <queue>#include <stack>#include <vector>#include <deque>#include <set>#include <map>#include <iostream>#include <algorithm>using namespace std;#define pi acos(-1.0)#define INF 0x3f3f3f3f#define N 200017int n, m, k, c;int Edgehead[N], dis[N];int vv[N], lay[N];struct{    int v,w,next;} Edge[20*N];bool vis[N];int cont[N];void init(){    memset(Edgehead,0,sizeof(Edgehead));    memset(vv,0,sizeof(vv));}void Addedge(int u,int v,int w){    Edge[k].next = Edgehead[u];    Edge[k].w = w;    Edge[k].v = v;    Edgehead[u] = k++;}int SPFA( int start){    queue<int>Q;    while(!Q.empty()) Q.pop();    for(int i = 1 ; i <= N ; i++ )        dis[i] = INF;    dis[start] = 0;    //++cont[start];    memset(vis,false,sizeof(vis));    vis[start] = 1;    Q.push(start);    while(!Q.empty())//直到队列为空    {        int u = Q.front();        Q.pop();        vis[u] = false;        for(int i = Edgehead[u] ; i!=-1 ; i = Edge[i].next)//注意        {            int v = Edge[i].v;            int w = Edge[i].w;            if(dis[v] > dis[u] + w)            {                dis[v] = dis[u]+w;                if( !vis[v] )//防止出现环,也就是进队列重复了                {                    Q.push(v);                    vis[v] = true;                }                //if(++cont[v] > n)//有负环                //   return -1;            }        }    }    return dis[n];}int main(){    int u, v, w;    int t;    int cas = 0;    scanf("%d",&t);    while(t--)    {        init();        scanf("%d%d%d",&n,&m,&c);        k = 1;        memset(Edgehead,-1,sizeof(Edgehead));                for(int i = 1; i <= n; i++)        {            scanf("%d",&u);//i 在第u层            lay[i] = u;            vv[u] = 1;        }                for(int i = 1; i < n; i++)        {            if(vv[i] && vv[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+lay[i],i,0);            if(lay[i] > 1)                Addedge(i,n+lay[i]-1,c);            if(lay[i] < n)                Addedge(i,n+lay[i]+1,c);        }        for(int i = 1 ; i <= m ; i++ )        {            scanf("%d%d%d",&u,&v,&w);            Addedge(u,v,w);//双向链表            Addedge(v,u,w);//双向链表        }        int s = SPFA(1);//从点1开始寻找最短路        if(s == INF)        {            s = -1;        }        printf("Case #%d: %d\n",++cas,s);    }    return 0;}



1 0
原创粉丝点击