題目描述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.
題解
借鑑了hzwer和網上的做法。。此題是個次短路的模板題
分三種情況更新
1.可以更新最短路 :原最短路變爲次短路 更新最短路
2.可以更新次短路但不能更新最短路 :更新次短路
3.次段路也可以更新次段路:那麼更新次短路
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define N 20005
#define inf 1<<29
#define ll long long
using namespace std;
int n,m,head[N];
ll d[N],d2[N];
int flag[N],cnt;
queue<int>q;
struct node{int to,w,next;}e[100005];
void insert(int x,int y,int z){
e[++cnt].to=y;e[cnt].w=z;e[cnt].next=head[x];head[x]=cnt;
}
void spfa(int s){
for(int i=1;i<=n;i++)d[i]=d2[i]=inf;
d[s]=0;//次短路起點不用爲0
flag[s]=1;
q.push(s);
while(!q.empty()){
int k=q.front();
q.pop();flag[k]=0;
for(int i=head[k];i;i=e[i].next){
int kk=e[i].to;
if(d[kk]>d[k]+e[i].w){
d2[kk]=d[kk];
d[kk]=d[k]+e[i].w;
if(!flag[kk]){
flag[kk]=1;
q.push(kk);
}
}
//如果可以更新最短路,那麼就讓它更新吧
//更新後的最短路是最短路,更新之前的最短路是當前的次短路
else if(d2[kk]>d[k]+e[i].w&&d[kk]<d[k]+e[i].w){
d2[kk]=d[k]+e[i].w;
if(!flag[kk]){
flag[kk]=1;
q.push(kk);
}
}
//如果不能更新最短路,但是可以更新次短路,那麼就讓它更新吧
if(d2[kk]>d2[k]+e[i].w){
d2[kk]=d2[k]+e[i].w;
if(!flag[kk]){
flag[kk]=1;
q.push(kk);
}
}
//次短路可以更新次短路,那麼就讓它更新吧
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
insert(u,v,w);
}
spfa(1);
if(d2[n]!=inf)printf("%d\n",d2[n]);
else printf("-1\n");
return 0;
}