2012年CCC加拿大高中生信息学奥赛
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 钻石 Diamond
题目描述 Description
Welcome to the Hungary Games! The streets of Budapest form a twisted network of one-way streets.
欢迎来到匈牙利游戏!布达佩斯(匈牙利首都)的街道形成了一个弯曲的单向网络。
You have been forced to join a race as part of a “Reality TV” show where you race through these streets, starting at the Sz´echenyi thermal bath (s for short) and ending at the Tomb of G¨ ul Baba (t for short).
你被强制要求参加一个赛跑作为一个TV秀的一部分节目,比赛中你需要穿越这些街道,从s开始,到t结束。
Naturally, you want to complete the race as quickly as possible, because you will get more promo- tional contracts the better you perform.
很自然的,你想要尽快的完成比赛,因为你的比赛完成的越好,你就能得到更多的商业促销合同。
However, there is a catch: any person who is smart enough to take a shortest s-t route will be thrown into the P´alv¨olgyi cave system and kept as a national treasure. You would like to avoid this fate, but still be as fast as possible. Write a program that computes a strictly-second-shortest s-t route.
但是,有一个需要了解的是,如果有人过于聪明找到从s到t的最短路线,那么他就被扔到国家极品人类保护系统中作为一个国家宝藏收藏起来。你显然要避免这种事情的发生,但是也想越快越好。写一个程序来计算一个从s到t的严格次短路线吧。
Sometimes the strictly-second-shortest route visits some nodes more than once; see Sample Input 2 for an example.
有的时候,严格次短路线可能访问某些节点不止一次。样例2是一个例子。
输入描述 Input Description
The first line will have the format N M, where N is the number of nodes in Budapest and M is the number of edges. The nodes are 1,2,...,N; node 1 represents s; node N represents t. Then there are M lines of the form A B L, indicating a one-way street from A to B of length L. You can assume that A != B on these lines, and that the ordered pairs (A,B) are distinct.
第一行包含两个整数N和M,N代表布达佩斯的节点个数,M代表边的个数。节点编号从1到N。1代表出发点s,N代表终点t。接下来的M行每行三个整数A B L,代表有一条从A到B的长度为L的单向同路。你可以认为A不等于B,也不会有重复的(A,B)对。
输出描述 Output Description
Output the length of a strictly-second-shortest route from s to t. If there are less than two possible lengths for routes from s to t, output −1.
输出从s到t的严格次短路的长度。如果从s到t的路少于2条,输出-1。
样例输入 Sample Input
样例输入1:
4 6
1 2 5
1 3 5
2 3 1
2 4 5
3 4 5
1 4 13
样例输入2:
2 2
1 2 1
2 1 1
样例输出 Sample Output
样例输出1:
11
样例输出2:
3
数据范围及提示 Data Size & Hint
对于样例1:
There are two shortest routes of length 10 (1 → 2 → 4,1 → 3 → 4) and the strictly-second- shortest route is 1 → 2 → 3 → 4 with length 11.
对于样例2:
The shortest route is 1 → 2 of length 1, and the strictly-second route is 1 → 2 → 1 → 2 of length 3.
求次短路的问题
注意spfa中的三条注释
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<queue>
5 using namespace std;
6 const int MAXN=100001;
7 const int maxn=0xfffffff;
8 struct node
9 {
10 int u;
11 int v;
12 int w;
13 int next;
14 }edge[MAXN];
15 int num=1;
16 int head[MAXN];
17 int n,m;
18 int dis[MAXN];
19 int vis[MAXN];// 是否在队列中
20 int tot=0;
21 int pre[MAXN];// 记录次短路
22 void spfa()
23 {
24 dis[1]=0;
25 vis[1]=1;
26 queue<int>q;
27 q.push(1);
28 while(q.size()!=0)
29 {
30 int p=q.front();
31 q.pop();
32 vis[p]=0;
33 for(int i=head[p];i!=-1;i=edge[i].next)
34 {
35 int to=edge[i].v;
36 if(dis[to]>dis[p]+edge[i].w)
37 {
38 pre[to]=dis[to];// 记录下更新之前的长度 即次长
39 dis[to]=dis[p]+edge[i].w;
40 //if(edge[i].v==n)tot++;
41 if(vis[to]==0)
42 {
43 q.push(to);
44 vis[to]=1;
45 }
46 }
47 else if(dis[to]!=dis[p]+edge[i].w&&pre[to]>dis[p]+edge[i].w)
48 {
49 pre[to]=dis[p]+edge[i].w;// 根据条件,此时需要更新,否则就不是次短路
50 if(vis[to]==0)
51 {
52 q.push(to);
53 vis[to]=1;
54 }
55 }
56 if(pre[to]>pre[p]+edge[i].w)// 同理,需要更新
57 {
58 pre[to]=pre[p]+edge[i].w;
59 if(vis[to]==0)
60 {
61 q.push(to);
62 vis[to]=1;
63 }
64 }
65 }
66 }
67 }
68 int main()
69 {
70 scanf("%d%d",&n,&m);
71 for(int i=1;i<=n;i++)
72 {
73 head[i]=-1;
74 dis[i]=maxn;
75 pre[i]=maxn;
76 }
77 for(int i=1;i<=m;i++)
78 {
79 scanf("%d%d%d",&edge[num].u,&edge[num].v,&edge[num].w);
80 edge[num].next=head[edge[num].u];
81 head[edge[num].u]=num++;
82 }
83 spfa();
84 if(pre[n]!=maxn)
85 printf("%d",pre[n]);
86 else
87 {
88 printf("-1");
89 }
90 return 0;
91 }