Description
Bessie 来到一个小农场,有时她想回老家看看她的一位好友。她不想太早地回到老家,因为她喜欢途中的美丽风景。她决定选择次短路径,而不是最短路径。
农村有 R (1 <= R <= 100,000) 条双向的路,每条路连接 N (1 <= N <= 5000) 个结点中的两个。结点的编号是 1..N。Bessie 从结点 1出发,她的朋友(目的地)在结点 N。
次短路径可以使用最短路径上的路,而且允许退回,即到达一个结点超过一次。次短路径是一种长度大于最短路径的路径(如果存在两条或多条最短路径存在,次短路径就是比它们长,且不比其他任何的路径长的路径)。
农村有 R (1 <= R <= 100,000) 条双向的路,每条路连接 N (1 <= N <= 5000) 个结点中的两个。结点的编号是 1..N。Bessie 从结点 1出发,她的朋友(目的地)在结点 N。
次短路径可以使用最短路径上的路,而且允许退回,即到达一个结点超过一次。次短路径是一种长度大于最短路径的路径(如果存在两条或多条最短路径存在,次短路径就是比它们长,且不比其他任何的路径长的路径)。
Input
Line 1: 两个用空格分隔的整数 N 和 R
Lines 2..R+1: 每行包含三个用空格分隔的整数: A, B, 和 D表示有一条路连接结点A和B,长度为D (1 <= D <= 5000)。
Lines 2..R+1: 每行包含三个用空格分隔的整数: A, B, 和 D表示有一条路连接结点A和B,长度为D (1 <= D <= 5000)。
Output
Line 1: 结点 1 到结点 N的次短路径长度。
Sample Input
4 4
1 2 100
2 4 200
2 3 250
3 4 100
Sample Output
450
Hint
【样例说明】
两条路径: 1 -> 2 -> 4 (长度 100+200=300) 以及 1 -> 2 -> 3 -> 4(长度 100+250+100=450)
两条路径: 1 -> 2 -> 4 (长度 100+200=300) 以及 1 -> 2 -> 3 -> 4(长度 100+250+100=450)
Summary
枚举每一条边加入两段端点到起点和终点的最短路,比最短路大的距离中最小的为最短路,设第i条边为(u,v),那么加入这条边形成的次短路为edge[i].w+dis[u]+dist[v]。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <cstdio> 2 using namespace std; 3 struct arr 4 { 5 int x,y,w,next; 6 }; 7 arr edge[500000]; 8 int ls[500000],dist[100000],dis[100000],n,m,min,d[100000]; 9 int ss(int x) 10 { 11 int h=0,t=1; 12 d[1]=x; 13 for (int i=1;i<=n;i++) 14 dist[i]=0xffffff; 15 dist[x]=0; 16 while (h<=t) 17 { 18 int i=ls[d[++h]]; 19 while (i!=0) 20 { 21 if (dist[edge[i].x]+edge[i].w<dist[edge[i].y]) 22 { 23 dist[edge[i].y]=dist[edge[i].x]+edge[i].w; 24 d[++t]=edge[i].y; 25 } 26 i=edge[i].next; 27 } 28 } 29 } 30 int main() 31 { 32 scanf("%d%d",&n,&m); 33 for (int i=1;i<=m;i++) 34 { 35 scanf("%d%d%d",&edge[i*2-1].x,&edge[i*2-1].y,&edge[i*2-1].w); 36 edge[i*2-1].next=ls[edge[i*2-1].x]; 37 ls[edge[i*2-1].x]=i*2-1; 38 edge[i*2].x=edge[i*2-1].y; 39 edge[i*2].y=edge[i*2-1].x; 40 edge[i*2].w=edge[i*2-1].w; 41 edge[i*2].next=ls[edge[i*2].x]; 42 ls[edge[i*2].x]=i*2; 43 } 44 ss(1); 45 min=0xffffff; 46 for (int i=1;i<=n;i++) 47 dis[i]=dist[i]; 48 ss(n); 49 for (int i=1;i<2*m;i++) 50 { 51 int z=edge[i].x,y=edge[i].y; 52 if (dis[z]+edge[i].w+dist[y]!=dis[n]&&dis[z]+edge[i].w+dist[y]<min) 53 min=dis[z]+edge[i].w+dist[y]; 54 } 55 printf("%d",min); 56 }