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.
InputThe 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 ) and C(1 <= C <= 10 ), 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 (1 <= l <= N), which is the layer of i node belong to.
Then come N lines each with 3 numbers, u, v (1 <= u, v < =N, u <> v) and w (1 <= w <= 10 ), which means there is an extra edge, connecting a pair of node u and v, with cost w.OutputFor 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
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
Sample Output
Case #1: 2 Case #2: 3
题意:给定一幅有层次的线路图,第一行输入 N,M,C 表示 N 个点和 M条边,每两层之间通过的费用是 C。
意思就是,除了走给定的路之外,我们还可以选择穿透层次,花费 C 的费用走到上一层或者下一层的任意一个节点,而不去走题目给定的边。
然后第二行 N个数就是表示第 i 个节点的层号,然后 M 行是描述边的。
思路:由于数据太大,一次可以设想每层都有一个入口和出口,层内的点到出口的距离为0,同样入口也是,层与层之间通过
让每层只出不进的出口连接上下两层只进不出的入口,权值是c,层内点与点之间的初始距离为无穷,有额外边的为额外值。
这样有N个初始的点,外加N个入口和N个出口,总共有3*N个点,边的数量也要变大。我将第N+1到2*N的点设为出口,将2*N+1到3*N之间的点
设为入口,具体内容见代码。
代码:
1 #include <cstdio> 2 #include <fstream> 3 #include <algorithm> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <string> 9 #include <cstring> 10 #include <map> 11 #include <stack> 12 #include <set> 13 #include <sstream> 14 #include <iostream> 15 #define mod 998244353 16 #define eps 1e-6 17 #define ll long long 18 #define INF 0x3f3f3f3f 19 using namespace std; 20 21 //数据开到比n*3要大 22 const int maxn = 1000005; 23 //结构体定义边的信息 24 struct node1 25 { 26 int y,z,next; 27 }; 28 node1 no[maxn]; 29 //结构体定义为优先结构 30 struct node2 31 { 32 //x表示当前点,len表示从起点到x的权值 33 int x,len; 34 friend bool operator < (node2 a,node2 b) 35 { 36 return a.len>b.len; 37 } 38 }; 39 //t表示测试样例数,n表示点数,m表示额外边数,p表示层与层之间的权值 40 int t,n,m,p; 41 //存放边的位置 42 int head[maxn]; 43 //存放起点到其他点的最短距离 44 int dis[maxn]; 45 //标记是否为最短点 46 bool vis[maxn]; 47 //表示边的数量 48 int s; 49 //函数用于储存边的信息 50 //表示从x到y的权值为z 51 void add(int x,int y,int z) 52 { 53 no[s].y=y; 54 no[s].z=z; 55 no[s].next=head[x]; 56 head[x]=s++; 57 } 58 //初始化层与层之间入口与出口的连接 59 //a表示层数,b表示层之间的权值 60 void init(int a,int b) 61 { 62 add(a+1,2*n+2,b); 63 for(int i=2;i<n;i++) 64 { 65 add(n+i,2*n+i-1,b); 66 add(n+i,2*n+i+1,b); 67 } 68 add(2*n,3*n-1,b); 69 } 70 //函数求最短路 71 void spfa() 72 { 73 //定义优先队列 74 priority_queue<node2> qu; 75 node2 q; 76 //初始化数据 77 memset(vis,0,sizeof(vis)); 78 memset(dis,INF,sizeof(dis)); 79 dis[1]=0; 80 q.x=1; 81 q.len=0; 82 //起点为1,权值为0 83 qu.push(q); 84 while(!qu.empty()) 85 { 86 q=qu.top(); 87 qu.pop(); 88 //如果当前点已找过,则无需再找 89 if(vis[q.x]) 90 { 91 continue; 92 } 93 //标记此点已找过 94 vis[q.x]=1; 95 //遍历此点连接的边 96 for(int i=head[q.x];i!=-1;i=no[i].next) 97 { 98 int u=no[i].y; 99 int v=no[i].z; 100 //更新起点到u的最小值 101 if(dis[u]>dis[q.x]+v) 102 { 103 dis[u]=dis[q.x]+v; 104 //将此点入队 105 node2 s; 106 s.x=u; 107 s.len=dis[u]; 108 qu.push(s); 109 } 110 } 111 } 112 } 113 int main() 114 { 115 scanf("%d",&t); 116 //ans表示测试的第几个样例 117 int ans=1; 118 while(t--) 119 { 120 s=1; 121 memset(head,-1,sizeof(head)); 122 scanf("%d %d %d",&n,&m,&p); 123 //初始化层 124 init(n,p); 125 int a,b,c; 126 //初始化点与层之间的权值 127 for(int i=1;i<=n;i++) 128 { 129 scanf("%d",&a); 130 add(i,a+n,0); 131 add(a+2*n,i,0); 132 } 133 //初始化点与点之间的权值 134 for(int i=1;i<=m;i++) 135 { 136 scanf("%d %d %d",&a,&b,&c); 137 add(a,b,c); 138 add(b,a,c); 139 } 140 spfa(); 141 printf("Case #%d: ",ans++); 142 //判断是否有解 143 if(dis[n]!=INF) 144 { 145 printf("%d\n",dis[n]); 146 } 147 else 148 { 149 printf("-1\n"); 150 } 151 } 152 }