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.
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.
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.
If there are no solutions, output -1.
2 3 3 3 1 3 2 1 2 1 2 3 1 1 3 3 3 3 3 1 3 2 1 2 2 2 3 2 1 3 4
Case #1: 2 Case #2: 3
题意:T组数据,每组第一行有三个数N,M,C,代表有N层,M条边的关系;
第二行是N数,代表每个点所在层数。
接下来M行,每行是三个数,u,v,w,表示u到v的权值是w,双向边。
求1到N的最短路径。如果存在就输出结果,不存在就输出-1.
把层也当成结点,所以层到层中的结点为0, 层到层的花费为C,
结点u到结点v之间的花费为w,为了方便起见,将层设为N+i结点
所以数组要开大一点,是原来的两倍。
不知道为什么用栈写会超时, 用队列也很快就过了。
具体请看代码。
#include <queue> #include <stack> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; #define inf 0x3f3f3f3f const int maxn = 100005; int lay[2*maxn]; int dis[2*maxn]; int book[2*maxn]; int head[2*maxn]; struct node{ int e, w; int next; void Node(int x, int y, int z) { e = x; w = y; next = z; } }e[40*maxn]; void init(int n, int m) { memset(lay, 0, sizeof(lay)); memset(book, 0, sizeof(book)); memset(dis, inf, sizeof(dis)); memset(head, -1, sizeof(head)); } void SPFA_sta() {//会超时 memset(book, 0, sizeof(book)); dis[1] = 0; int pre, nex; stack<int> sta; sta.push(1); while(!sta.empty()) { pre = sta.top(); sta.pop(); book[pre] = 0; for(int i = head[pre]; i != -1; i = e[i].next) { nex = e[i].e; if(dis[nex] > dis[pre] + e[i].w) { dis[nex] = dis[pre] + e[i].w; if(!book[nex]) { book[nex] = 1; sta.push(nex); } } } } } void SPFA_que() {//358ms memset(book, 0, sizeof(book)); dis[1] = 0; int pre, nex; queue<int> q; q.push(1); while(!q.empty()) { pre = q.front(); q.pop(); book[pre] = 0; for(int i = head[pre]; i != -1; i = e[i].next) { nex = e[i].e; if(dis[nex] > dis[pre] + e[i].w) { dis[nex] = dis[pre] + e[i].w; if(!book[nex]) { book[nex] = 1; q.push(nex); } } } } } int main() { int T; int li, t; int N, M, C; int u, v, w; int Case = 1; scanf("%d", &T); while(T--) { t = 0; scanf("%d %d %d", &N, &M, &C); init(N, M); for(int i = 1; i <= N; i++) { scanf("%d", &li); lay[i] = li; book[li] = 1; } for(int i = 1; i < N; i++) { if(book[i] && book[i+1]) {//层与层建边 e[t].Node(N+i, C, head[i+N+1]);//将层当成结点建边 head[i+N+1] = t; t++; e[t].Node(N+i+1, C, head[N+i]); head[i+N] = t; t++; } } for(int i = 1; i <= N; i++) {//层与点建边 e[t].Node(i, 0, head[lay[i]+N]); head[lay[i]+N] = t; t++; if(lay[i] > 1) { e[t].Node(lay[i]-1+N, C, head[i]);//与上一层建边 head[i] = t; t++; } if(lay[i] < N){ e[t].Node(lay[i]+1+N, C, head[i]);//与下一层建边 head[i] = t; t++; } } for(int i = 1; i <= M; i++) {//点与点建边 scanf("%d %d %d", &u, &v, &w);//双向边 e[t].Node(v, w, head[u]); head[u] = t; t++; e[t].Node(u, w, head[v]); head[v] = t; t++; } SPFA_que(); //SPFA_sta(); if(dis[N] != inf) printf("Case #%d: %d\n", Case++, dis[N]); else printf("Case #%d: -1\n", Case++); } return 0; }