直接翻譯了ios
Descriptionsspa
Bessie搬到了一個新的農場,有時候他會回去看他的老朋友。可是他不想很快的回去,他喜歡欣賞沿途的風景,因此他會選擇次短路,由於她知道必定有一條次短路。
這個鄉村有R(1<=R<=100000)條雙向道路,每一條鏈接N(1<=N<=5000)個點中的兩個。Bessie在1號節點,他的朋友家是n號節點Input第一行:兩個整數N和R
接下來R行:每行包含三個整數,A,B,D,表示一條鏈接A與B的長度爲D的路徑Output輸出1到n的次短路.net
Sample Input翻譯
4 4 1 2 100 2 4 200 2 3 250 3 4 100Sample Outputcode
450
Hintblog
求從s到t的次短路徑有兩種狀況:一、起點s到某個頂點u的最短路+d(u,t)。二、起點到某個頂點u的次短路+d(u,t)。ip
因此更新路徑的時候須要把最短路徑和次短路徑兩個都記錄下來。ci
送一組數據get
4 2
1 2 100
2 4 200
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <queue> #include <string>1 #include <cstring> #include <map> #include <stack> #include <set> #include <sstream> #define IOS ios_base::sync_with_stdio(0); cin.tie(0) #define Mod 1000000007 #define eps 1e-6 #define ll long long #define INF 0x3f3f3f3f #define MEM(x,y) memset(x,y,sizeof(x)) #define Maxn 5000+5 #define P pair<int,int>//first最短路徑second頂點編號 using namespace std; int N,R; struct edge { int to,dis; edge(int to,int dis):to(to),dis(dis) {} }; vector<edge>G[Maxn];//G[i] 從i到G[i].to的距離爲dis int d[Maxn][Maxn];//d[i][j]從i到j的最短距離 int d2[Maxn][Maxn];//d[i][j]從i到j的次短距離 void Dijk(int s) { priority_queue<P,vector<P>,greater<P> >q;//按first從小到大出隊 for(int i=0; i<=N; i++)//初始化s到全部地方的最短路,次短路都是inf d[s][i]=INF,d2[s][i]=INF; d[s][s]=0; q.push(P(0,s)); while(!q.empty()) { P p=q.top(); q.pop(); int v=p.second;//點v if(d2[s][v]<p.first)//大於次短路徑,確定會大於最短路徑,不用管他了 continue; for(int i=0; i<G[v].size(); i++) { edge e=G[v][i];//枚舉與v相鄰的點 int td=p.first+e.dis;//s到v的距離+v到e.to的距離 if(d[s][e.to]>td)//s到e.to的最短路小於dt,更新d[s][e.to] { swap(d[s][e.to],td); q.push(P(d[s][e.to],e.to)); } if(d[s][e.to]<td&&d2[s][e.to]>td)//td大於最短路,小於次短路,即td能夠替換次短路 { d2[s][e.to]=td; q.push(P(d2[s][e.to],e.to)); } } } } int main() { IOS; cin>>N>>R; for(int i=0; i<R; i++) { int u,v,d; cin>>u>>v>>d; G[u].push_back(edge(v,d)); G[v].push_back(edge(u,d)); } Dijk(1);//城市1到各個城市的最短距離,次短路 cout<<d2[1][N]<<endl; return 0; }