Welcome to the Hungary Games!
题目描述 Description
欢迎来到匈牙利游戏!布达佩斯(匈牙利首都)的街道形成了一个弯曲的单向网络。
你被强制要求参加一个赛跑作为一个TV秀的一部分节目,比赛中你需要穿越这些街道,从s开始,到t结束。
很自然的,你想要尽快的完成比赛,因为你的比赛完成的越好,你就能得到更多的商业促销合同。
但是,有一个需要了解的是,如果有人过于聪明找到从s到t的最短路线,那么他就被扔到国家极品人类保护系统中作为一个国家宝藏收藏起来。你显然要避免这种事情的发生,但是也想越快越好。写一个程序来计算一个从s到t的严格次短路线吧。
有的时候,严格次短路线可能访问某些节点不止一次。样例2是一个例子。
输入描述 Input Description
第一行包含两个整数N和M,N代表布达佩斯的节点个数,M代表边的个数。节点编号从1到N。1代表出发点s,N代表终点t。接下来的M行每行三个整数A B L,代表有一条从A到B的长度为L的单向同路。你可以认为A不等于B,也不会有重复的(A,B)对。
输出描述 Output Description
输出从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
这道题叫次短路……
和最短路类似,但略有不同
主要就是开第二个距离数组dist2(也就是代码中的cdl(次短路))
用来存放次短路长度
当然也可以用结构体储存辣
下面是代码~_~
#include<queue>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
long long tot,dist1[200010],cdl[200010],head[200010],Ts,Te,T,C;
bool passby[200010];
struct Edge
{
int next,to,dist;
}edge[900010];
void add(int from,int to,int dd)//dd=距离;
{
edge[++tot].to=to;//加终点
edge[tot].dist=dd;//加距离
edge[tot].next=head[from];//更新上条路
head[from]=tot;//更新这条路
}
queue<int> q;
void spfa(int s)
{
dist1[s]/*=cdl[s]*/=0;
passby[s]=1;
q.push(s);
for(;!q.empty();)
{
int x=q.front();
passby[x]=0;
q.pop();
for(int i=head[x];i;i=edge[i].next)
{
Edge e=edge[i];
if(dist1[e.to]>dist1[x]+e.dist)
{
cdl[e.to]=dist1[e.to];
dist1[e.to]=dist1[x]+e.dist;
if(!passby[e.to])
{
passby[e.to]=1;
q.push(e.to);
}
}
else if(cdl[e.to]>dist1[x]+e.dist&&dist1[e.to]<dist1[x]+e.dist)//注意&&后的东西
{
cdl[e.to]=dist1[x]+e.dist;
if(!passby[e.to])
{
passby[e.to]=1;
q.push(e.to);
}
}
else if(cdl[e.to]>cdl[x]+e.dist)
{
cdl[e.to]=cdl[x]+e.dist;
if(!passby[e.to])
{
passby[e.to]=1;
q.push(e.to);
}
}
}
}
}
int main()
{
cin>>T>>C;
for(int i=0;i<=C+5;i++)dist1[i]=cdl[i]=0x7ffffffffffffff;
for(int i=1;i<=C;i++)
{
int Rs,Re,Ci;
cin>>Rs>>Re>>Ci;
add(Rs,Re,Ci);
}
spfa(1);
if(cdl[T]!=0x7ffffffffffffff)
cout<<cdl[T];
else
cout<<"-1" ;
return 0;
}