题目描述 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.
次短路模板
思路:
如果最短路可以被更新,那么直接更新最短路。次短路等于更新前的最短路。
如果最短路不可以被更新,次短路可以被更新,那么就更新次短路。
如果次短路可以被次短路更新,就更新~
如果忘记了以上的证明过程,就去调试一遍样例1。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<deque>
using namespace std;
const int maxn=100000+10;
int first[maxn],nxt[maxn],tot=0;
int dist[maxn],ci[maxn];
int n,m;
bool used[maxn];
struct edge
{
int f,t,v;
}l[maxn];
void build(int f,int t,int v)
{
l[++tot]=(edge){f,t,v};
nxt[tot]=first[f];
first[f]=tot;
return;
}
void spfa_slf(int s)
{
deque<int>q;
q.push_front(s);
used[s]=1;
dist[s]=0;
//ci[i]=0 这里不能对次短路进行初始化(有环的话不成立)如:1->2 1 2—>1 1
while(!q.empty())
{
int f=q.front();
q.pop_front();
used[f]=0;
for(int i=first[f];i!=-1;i=nxt[i])
{
int w=l[i].t;
if(dist[w]>dist[f]+l[i].v)
{
ci[w]=dist[w];
dist[w]=dist[f]+l[i].v;
if(!used[w])
{
used[w]=1;
if(q.empty()) q.push_front(w);
else if(dist[w]<=dist[q.front()]) q.push_front(w);
else q.push_back(w);
}
}
else if(dist[w]<dist[f]+l[i].v&&dist[f]+l[i].v<ci[w])
{
ci[w]=dist[f]+l[i].v;
if(!used[w])
{
used[w]=1;
if(q.empty()) q.push_front(w);
else if(dist[w]<=dist[q.front()]) q.push_front(w);
else q.push_back(w);
}
}
else if(ci[w]>ci[f]+l[i].v)
{
ci[w]=ci[f]+l[i].v;
if(!used[w])
{
used[w]=1;
if(q.empty()) q.push_front(w);
else if(dist[w]<=dist[q.front()]) q.push_front(w);
else q.push_back(w);
}
}
}
}
}
int main()
{
int a,b,c;
memset(first,0xfff,sizeof(first));
memset(dist,0x3f3f3f3f,sizeof(dist));
memset(ci,0x3f3f3f3f,sizeof(ci));
memset(used,0,sizeof(used));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
build(a,b,c);
}
spfa_slf(1);
if(ci[n]>0&&ci[n]<0x3f3f3f3f) cout<<ci[n]<<'\n';
else cout<<"-1"<<'\n';
return 0;
}
优化时如果写成“<=”会快那么一丁点。
if(q.empty()) q.push_front(w);
else if(dist[w]<=dist[q.front()]) q.push_front(w);
else q.push_back(w);