1. 程式人生 > >[poj3255]次短路

[poj3255]次短路

sin lsp borde tor pop cin vector scan 條件

給出一張有n個點和m條雙向邊的圖,要求求出1到n的次短路的長度。一條邊可以多次通過。

輸入格式:

第一行為兩個整數n和m。接下來的m行每行三個整數ai,bi,vi,分別表示這條路連著的兩個點和他的長度。

輸出格式:

一個整數,表示次短路的長度。(次短路長度必須大於最短路,數據保證有解)

樣例輸入

樣例輸出

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

450

樣例解釋:

最短:1->2->4。

次短:1->2->3->4。

數據範圍:

對於 100%的數據:1<=n、vi

<=5000,1<=m<=100000。

首先更新的條件有兩個:小於最短距離,大於最短距離且小於次短距離

如果新更新出的值小於最短路的值,那麽把最短路的值變成新更新的值,次短路的值變成最短路的值

註意:要把現最短路的值和現次短路的值都進堆

如果新更新出的值大於最短距離且小於次短距離,那麽僅更新次短路的值,且將次短路的值入堆

同樣出堆的條件也應放寬到小於等於次短路徑

註意:初始化時僅有S的最短路長度為0,其他都為inf(包括次短路長度)

#include<iostream>
#include<cstdio>
#include<queue>
#include
<cstring> using namespace std; int h[5100],to[200100],next[200100],k=0,cost[200100]; typedef pair<int,int> P; priority_queue<P,vector<P>,greater<P> > q; int dist[5100][2]; void ins(int u,int v,int w){next[++k]=h[u];h[u]=k;to[k]=v;cost[k]=w;} void dij(int S) { memset(dist,127/2,sizeof
(dist)); dist[S][0]=0;q.push(P(0,S)); while(!q.empty()) { P p=q.top();q.pop();int u=p.second; if(dist[u][1]<p.first)continue; for(int i=h[u];i;i=next[i]) { int v=to[i]; if(p.first+cost[i]<dist[v][0]) { dist[v][1]=dist[v][0];dist[v][0]=p.first+cost[i]; q.push(P(dist[v][0],v));q.push(P(dist[v][1],v)); } else if(p.first+cost[i]<dist[v][1]&&p.first+cost[i]!=dist[v][0]) { dist[v][1]=p.first+cost[i]; q.push(P(dist[v][1],v)); } } } } int main() { freopen("short.in","r",stdin);freopen("short.out","w",stdout); int n,m;scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int x,y,z;scanf("%d%d%d",&x,&y,&z);ins(x,y,z);ins(y,x,z); } dij(1); printf("%d",dist[n][1]); return 0; }

[poj3255]次短路