poj3255 次短路Dijkstra
阿新 • • 發佈:2019-01-08
挑戰程式設計競賽上的題目。
題意:給一個邊權都是正的無向圖,求1到n的次短路。
分析:
考慮s->v的次短路,假設s-v的最短路為s->...->u>v,到v的次短路等於到u的次短路加上cost(u,v)和到k的最短路加上cost(k,v)中的最小但是大於u->v的最短路的值。那麼只要保證在求最短路的過程中同時儲存次短路就可以了。
程式碼。
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> #define INF 0x7fffffff using namespace std; typedef pair<int,int> P; struct edge{ int to,v; edge(int to,int v):to(to),v(v){} edge(){} }; const int maxn = 5005; const int maxe = 100005; int V,E; vector<edge> g[maxn]; int d[maxn],d2[maxn];//最短距離和次短距離 void dijkstra(int s) { priority_queue<P,vector<P>,greater<P> > pq; for(int i=1;i<=V;i++) { d[i]=INF; d2[i]=INF; } d[s]=0; pq.push(P(0,s)); while(pq.size()) { P nowe=pq.top();pq.pop(); if(nowe.first>d2[nowe.second]) continue; //如果這個距離比當前次短路長continue for(int v=0;v<(int)g[nowe.second].size();v++) { edge nexte=g[nowe.second][v]; int dis=nowe.first+nexte.v; if(d[nexte.to]>dis) { swap(dis,d[nexte.to]); pq.push(P(d[nexte.to],nexte.to)); } if(d2[nexte.to]>dis&&d[nexte.to]<dis)//保證最短路是小於這個次短路的 { d2[nexte.to]=dis; pq.push(P(d2[nexte.to],nexte.to));//次短路的點進入pq } } } } int main() { int s;//起點 scanf("%d%d",&V,&E); { for(int i=1;i<=V;i++) g[i].clear(); for(int i=1;i<=E;i++) { int f,t,v; scanf("%d%d%d",&f,&t,&v); g[f].push_back(edge(t,v)); g[t].push_back(edge(f,v)); } s=1;//這題預設起點為1 dijkstra(s); printf("%d\n",d2[V]); } return 0; }