1. 程式人生 > >第二短路

第二短路

oj1220

貝茜把家搬到了一個小農場,但她常常回到FJ的農場去拜訪她的朋友。貝茜很喜歡路邊的風景,不想那麼快地結束她的旅途,於是她每次回農場,都會選擇第二短的路徑,而不象我們所習慣的那樣,選擇最短路。

貝茜所在的鄉村有R(1<=R<=100,000)條雙向道路,每條路都聯結了所有的N(1<=N<=5000)個農場中的某兩個。貝茜居住在農場1,她的朋友們居住在農場N(即貝茜每次旅行的目的地)。

貝茜選擇的第二短的路徑中,可以包含任何一條在最短路中出現的道路,並且,一條路可以重複走多次。當然咯,第二短路的長度必須嚴格大於最短路(可能有多條)的長度,但它的長度必須不大於所有除最短路外的路徑的長度。

第二短路顧名思義要比第一短路要長,必剩餘其他路短,所以比較是肯定要比較兩次的啦,那麼對於第二短路我們也要讓它儘可能的短,所以我們用第一短路來尋找第二短路;

所以我們開兩個陣列,dis1,dis2,分別表示第一短路和第二短路;

所以

if(dis1[v]>dis1[x]+a[i].v)
{
dis2[v]=dis1[v];


dis1[v]=dis1[x]+a[i].v;
if(!vis[v]) vis[v]=1,q.push(v);
}
else if(dis1[x]+a[i].v<dis2[v]&&dis1[x]+a[i].v>dis1[v])
{//尋找滿足條件的第二短路,二個條件是為了滿足能夠更新dis2(因為只有滿足小於除最短路外的所有路)
dis2[v]=dis1[x]+a[i].v;
if(!vis[v]) q.push(v),vis[v]=1;
}
if(dis2[x]+a[i].v<dis2[v])
{//第二短路也需要找到最短路,比較更新;
dis2[v]=dis2[x]+a[i].v;
if(!vis[v]) q.push(v),vis[v]=1;

}

這樣不斷更新第二短路,就找到我們想要的answer啦;

程式碼

#include<bits/stdc++.h>
using namespace std;
#define N 5010
#define M 100010
int n,lin[N],tot,vis[N],dis1[N],xx,yy,vv,m,dis2[N];
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch))    {if(ch=='-') f=-1;ch=getchar();}
    
while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } struct gg { int y,next,v; }a[M<<1]; inline void init(int xx,int yy,int vv) { a[++tot].y=yy; a[tot].next=lin[xx]; a[tot].v=vv; lin[xx]=tot; } inline void spfa() { queue<int> q; memset(vis,0,sizeof(vis)); memset(dis1,127,sizeof(dis1)); memset(dis2,127,sizeof(dis2)); dis1[1]=0;vis[1]=1;q.push(1); while(!q.empty()) { int x=q.front();q.pop();vis[x]=0; for(int i=lin[x];i;i=a[i].next) { int v=a[i].y; if(dis1[v]>dis1[x]+a[i].v) { dis2[v]=dis1[v]; dis1[v]=dis1[x]+a[i].v; if(!vis[v]) vis[v]=1,q.push(v); } else if(dis1[x]+a[i].v<dis2[v]&&dis1[x]+a[i].v>dis1[v]) { dis2[v]=dis1[x]+a[i].v; if(!vis[v]) q.push(v),vis[v]=1; } if(dis2[x]+a[i].v<dis2[v]) { dis2[v]=dis2[x]+a[i].v; if(!vis[v]) q.push(v),vis[v]=1; } } } } int main() { n=read();m=read(); for(int i=1;i<=m;i++) { xx=read();yy=read();vv=read(); init(xx,yy,vv); init(yy,xx,vv); } spfa(); cout<<dis2[n]<<endl; return 0; }
View Code