次短路

题目描述

给定N个节点,M条无向边的图,求1号节点到N号节点次短路的长度

备注:次短路是长度大于最短路中最短的路径

输入

第一行,两个整数N,M

接下来M行:每行3个整数u,v,c,表示u,v之间有一条长度为c的边

其中N<=5000,M<=100000,0<c<=10000

输出

一行一个整数,表示次短路的长度

样例输入

4 4
1 2 100
2 4 200
2 3 250
3 4 100

样例输出

450

提示

最短路:1->2->4,长度为300

次短路:1->2->3->4,长度为450

#include<cstdio>
#define inf 1e9
#define N 100005
#define S1 dis[x]+e[i].v
#define S2 sdis[x]+e[i].v
using namespace std;
//--------------------------
template<class T>inline void cin(T&x){
    static char c;static int y;
    for(c=getchar(),x=0,y=1;c<48||57<c;c=getchar())if(c=='-')y=-1;
    for(;48<=c&&c<=57;c=getchar())x=((x+(x<<2))<<1)+(c^'0');
    x*=y;}
void outint(int x){if(x>=10) outint(x/10);putchar(x%10+'0');}
//--------------------------optimization above
struct node{int to,next,v;}e[N<<1];//e:edge
int head[N],cnt;//cnt:counter,head:point
void insert(int x, int y, int v){e[++cnt].to=y;e[cnt].next=head[x];e[cnt].v=v;head[x]=cnt;}
int n,m,dis[N],sdis[N],q[N<<2];
bool inq[N];
void SPFA(){for(int i=1;i<=n;i++)dis[i]=sdis[i]=inf;
    dis[1]=0; q[0]=1; int l=0,r=1,t; inq[1]=1;//initialization,set the first dis as 0,and push it into the queue,and make it enter_mark true
    while (l<r){int x=q[l++];//if the queue is empty,just set x as the queue_head ,and then renew the queue_head
        for (int i=head[x];i;i=e[i].next){t=e[i].to;//from the first point ,keep going next
        if (dis[t]>S1){sdis[t]=dis[t];dis[t]=S1;if (!inq[t])inq[t]=1,q[r++]=t;}
        //old solution can make better case
        //make second_solution as the old solution,renew the old solution,++++if it has not enter queue,enter it and then mark it true
        if (dis[t]<S1&&sdis[t]>S1){sdis[t]=S1;if (!inq[t])inq[t]=1,q[r++]=t;}
        //second_solution can make better case
        //change it and then just as++++
        if (sdis[t]>S2){sdis[t]=S2;if (!inq[t])inq[t]=1,q[r++]=t;}
        //if can make second_solution_map's better case
        //change it and then just as++++
        }inq[x]=0;//make it false
    }
}
int main(){cin(n),cin(m);int x,y,v;
    for (int i=1; i<=m; i++){cin(x),cin(y),cin(v);insert(x,y,v);insert(y,x,v);}//make edge
    SPFA();outint(sdis[n]);return 0;
}//quick and easy,so this is the best solution 
//noted by franzl lang

代码实现如上,程序是最好的语言、、