题目大意:给n个点R条边,求1-n的次短路。
解题思路:要求到点v次短路,有两种可能:
1,某个顶点u的最短路 + u->v
2,u的次短路 + u->v
所以我们对于每一个点更新的时候,把它的次短路记录下来,也压进堆来更新就好了。
具体怎么实现倒是一个比较巧的方法:原来更新是dist[e.to] = d2,现在是swap(dist[e.to], d2),这样d2就直接成了当前更新的前一个距离,后面更新dist2的时候直接用就可以了,不需要另开变量。
还有一个小细节就是dist1[1] = 0,dist2[1] = inf,就不说了.
AC Code:
//My Conquest Is the Sea of Stars.
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define gcd __gcd
#define pb push_back
#define mp make_pair
#define lowbit(x) x & (-x)
#define PII pair<int, int>
#define all(x) x.begin(), x.end()
#define rep(i, a, b) for(int i = a; i <= (b); i++)
#define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int mod = (int)1e9 + 7;
const int maxn = (int)5e3 + 5;
const int maxm = (int)5205;
using namespace std;
struct edge{
int to, cost;
edge(){}
edge(int to_, int cost_){
to = to_, cost = cost_;
}
};
vector<edge> G[maxn];
int dist[maxn], dist2[maxn];
int n, m;
void dij(){
priority_queue<PII, vector<PII>, greater<PII> > q;
memset(dist, 0x3f, sizeof(dist));
memset(dist2, 0x3f, sizeof(dist2));
dist[1] = 0;
q.push(PII(0, 1));
while(!q.empty()){
PII p = q.top(); q.pop();
int v = p.se, d = p.fi;
if(dist2[v] < d) continue;
int len = G[v].size();
rep(i, 0, len - 1){
edge &e = G[v][i];
int d2 = d + e.cost;
if(dist[e.to] > d2){
swap(dist[e.to], d2);
q.push(PII(dist[e.to], e.to));
}
if(dist2[e.to] > d2 && dist[e.to] < d2){
dist2[e.to] = d2;
q.push(PII(dist2[e.to], e.to));
}
}
}
}
int main()
{
scanf("%d %d", &n, &m);
rep(i, 1, m){
int u, v, w; scanf("%d %d %d", &u, &v, &w);
G[u].pb(edge(v, w));
G[v].pb(edge(u, w));
}
dij();
printf("%d\n", dist2[n]);
return 0;
}