The Shortest Path in Nya Graph
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
T \le 20
T≤20) , indicating the number of test cases.
For each test case, first line has three numbers N, M (
0
≤
N
,
M
≤
1
0
5
0 \le N, M \le 10^5
0≤N,M≤105) and C(
1
≤
C
≤
1
0
3
1 \le C \le 10^3
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
≤
l
i
≤
N
1 \le l_i \le N
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
1 \le u, v \le N, u \ne v
1≤u,v≤N,u=v) and w (
1
≤
w
≤
1
0
4
1 \le w \le 10^4
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
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个点,每个点都属于某一层,从第x层的点可以到第x+1层的任意点,花费为c,边为双向边,所以x+1层的点到x层的点花费也为c。另外有额外m条双向边,求1号点到n号点的最小花费。
题解:
直接相邻层直接暴力所有点建边显然不行。所以考虑对每一层额外建两个点,分别代表入点和出点:
对于层内点,由入点向所有层内点连边,花费0;
所有层内点向出点连边,花费0,;
入点向出点连边,花费0;
每层出点连向相邻层的入点,花费为c;
额外边直接建边即可。
需要注意的是,如果某一层是空的,不能向其相邻层建边。
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<ctype.h>
#include<cstring>
#include<map>
#include<queue>
#include<stack>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define eps 1e-6
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 600100;
const int mod = 1000000007;
struct node{
int to, w;
node(){}
node(int a, int b):to(a),w(b){}
};
vector<node> g[maxn];
//b:该层是否 不为空
int dis[maxn], b[maxn];
void init(int n);
void dijkstra();
int main()
{
int t, n, m, c, i, j, k;
scanf("%d", &t);
for(int z=1;z<=t;z++)
{
scanf("%d %d %d", &n, &m, &c);
init(n);
for(i=1;i<=n;i++){
scanf("%d", &j);
b[j] = 1;
g[n+j].push_back(node(i, 0));
g[i].push_back(node(n+n+j, 0));
}
for(i=1;i<=n;i++){
if(b[i]) g[n+i].push_back(node(n+n+i, 0));
if(b[i] && b[i-1]) g[n+n+i].push_back(node(n+i-1, c));
if(b[i] && b[i+1]) g[n+n+i].push_back(node(n+i+1, c));
}
for(i=1;i<=m;i++){
int fr, to, nex;
scanf("%d %d %d", &fr, &to, &nex);
g[fr].push_back(node(to, nex));
g[to].push_back(node(fr, nex));
}
dijkstra();
if(dis[n] == INF)printf("Case #%d: -1\n", z);
else printf("Case #%d: %d\n", z, dis[n]);
}
return 0;
}
void init(int n)
{
for(int i=0;i<3*n+30;i++)
g[i].clear(), dis[i] = INF, b[i] = 0;
}
void dijkstra()
{
priority_queue<P, vector<P>, greater<P> > que;
que.push(P(0, 1));
dis[1] = 0;
while(!que.empty())
{
P p = que.top();que.pop();
if(p.first>dis[p.second])continue;
for(int i=0;i<g[p.second].size();i++)
{
node e = g[p.second][i];
if(dis[e.to] > p.first + e.w)
{
dis[e.to] = p.first+e.w;
que.push(P(dis[e.to], e.to));
}
}
}
}