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
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
题目理解:这里主要的点就是建边,之后Dijkstra和SPFA都可以。
#include<iostream>
#include<cstring>
#include<map>
#include<queue>
#include<stdio.h>
using namespace std;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f;
const int maxn=100010;
int head[maxn*3],dis[maxn*3],vis[maxn*3]; //由于建边的缘故,这里需扩大3倍
int cnt,n,m,c;
struct Edge
{
int v,w,next;
}e[maxn*6];
void Init() //初始化
{
cnt=1;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(dis,INF,sizeof(dis));
}
void add(int u,int v,int w) //前向星
{
e[cnt].v=v;
e[cnt].w=w;
e[cnt].next=head[u];
head[u]=cnt++;
}
void Dijkstra(int s)
{
dis[s]=0;
priority_queue<P,vector<P>,greater<P> >que;
que.push(P(0,s));
while(!que.empty())
{
P p=que.top();
que.pop();
int u=p.second;
if(vis[u])
continue;
vis[u]=1;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].v;
int w=e[i].w;
if(!vis[v]&&dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
que.push(P(dis[v],v));
}
}
}
}
int main()
{
int t,k=1;
scanf("%d",&t);
while(t--)
{
Init();
scanf("%d%d%d",&n,&m,&c);
for(int i=1;i<n;i++) //第i层和第i+1层建立一条权值为c的边
{
add(n+i,n*2+i+1,c);
add(n+i+1,n*2+i,c);
}
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
add(i,n+x,0); //1到n的每一个节点可以无花费的到达他所在的x层节点
add(2*n+x,i,0); //从x层节点可以无花费的到达该节点
}
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
Dijkstra(1);
printf("Case #%d: ",k++);
if(dis[n]==INF||n==0)
cout<<"-1"<<endl;
else
cout<<dis[n]<<endl;
}
return 0;
}