The Shortest Path in Nya Graph
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1279 Accepted Submission(s): 286
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 <= 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
这题 ,就是一个最短路,但是在建图的过程是很难啊,主要是,不同层之间的关系,如果是直接建的话,复杂度,达到n*n,这样是不可接受的,所以,这题主要是拆点,把第0到第i-1层想象成点,这样,我们规过n+2*i为第i层入点,n+2*(i+1)是第i层出点,这样,我们就可以通过原点与这些想象的点想连,就可以在线性时间里,把图建好了!
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string.h>
#include <queue>
using namespace std;
#define typec int
const typec inf =0x4f4f4f4f;
#define E 1000500
#define V 300500
vector<int > vec[V];
typec cost[E],dist[V];
int e,pnt[E],nxt[E],head[V],prev[V],vis[V],num[V];
struct qnode {
int v;typec c;
qnode (int vv=0,typec cc=0):v(vv),c(cc){}
bool operator <(const qnode & r)const {return c>r.c;}
};
void dijkstra(int n,const int src){
qnode mv;
int i,j,k,pre;
priority_queue<qnode> que;
vis[src]=1;dist[src]=0;
que.push(qnode(src,0));
for(pre=src,i=1;i<n;i++){
for(j=head[pre];j!=-1;j=nxt[j]){
k=pnt[j];
if(vis[k]==0&&
dist[pre]+cost[j]<dist[k]){
dist[k]=dist[pre]+cost[j];
que.push(qnode(pnt[j],dist[k]));
prev[k]=pre;
}
}
while(!que.empty()&&vis[que.top().v]==1){
que.pop();
}
if(que.empty())break;
mv=que.top();que.pop();
vis[pre=mv.v]=1;
}
}
inline void addedge(int u,int v,typec c){
pnt[e]=v;cost[e]=c;nxt[e]=head[u];head[u]=e++;
}
int main()
{
int i,u,v,n,m,temp;typec c;
int tcase,tt=1,s,ee;
scanf("%d",&tcase);
while(tcase--){
scanf("%d%d%d",&n,&m,&c);
e=0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(prev,-1,sizeof(prev));
int n3=3*n;
for(i=0;i<n3;i++)
vec[i].clear();
for(i=0;i<n;i++){
scanf("%d",&temp);
temp--;
addedge(n+2*temp+1,i,0);
addedge(i,n+2*temp,0);
}
for(i=0;i<n3;i++)dist[i]=inf;
for(i=0;i<n-1;i++)
{
addedge(n+2*i,n+2*(i+1)+1,c);
addedge(n+2*(i+1),n+2*i+1,c);
}
for(i=0;i<m;i++){
scanf("%d%d%d",&s,&ee,&c);
s--,ee--;
addedge(s,ee,c);
addedge(ee,s,c);
}
dijkstra(n3,0);
if(dist[n-1]!=inf)
printf("Case #%d: %d\n",tt++,dist[n-1]);
else
printf("Case #%d: -1\n",tt++);
}
return 0;
}