题目:传送门
思路:
仍然是用dijkstra,不过开两个数组,一个保存最短距离,一个保存次短距离,更新距离和dijkstra模板一样的。要注意的是,更新完最短距离dis1[e.to]时,原先的数据(也就变成了次短距离)要保存着。(就是代码里面的swap)
Code:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int inf = 0x3f3f3f3f;
const int maxn = 100007;
struct Edge {
int to, dist;
};
struct HeapNode {
int u, d;
bool operator < (const HeapNode& other) const {
return d > other.d;
}
};
int dis1[maxn];//最短路
int dis2[maxn];//次短路
vector<Edge> G[maxn];
int v, e;
priority_queue<HeapNode> q;
void dijkstra(int s) {
fill(dis1, dis1+1+v, inf);
fill(dis2, dis2+1+v, inf);
dis1[s] = 0;
q.push(HeapNode {s, 0});
while (!q.empty()) {
HeapNode tp = q.top();q.pop();
int u = tp.u;
for (int i=0;i<G[u].size();i++) {
Edge& e = G[u][i];
int ds = tp.d + e.dist;
if (dis1[e.to] > ds) {
swap(dis1[e.to], ds);//把dis1[u]原来的值保存到d_里面,下面还要用
q.push(HeapNode {e.to, dis1[e.to]});
}
if (dis2[e.to] > ds && dis1[e.to] < ds) {//确保可以更新,但不小于dis1里的最小
dis2[e.to] = ds;
q.push(HeapNode {e.to, dis2[e.to]});
}
}
}
}
int main()
{
int from, to, d;
scanf("%d %d", &v, &e);
for (int i=0;i<e;i++) {
scanf("%d %d %d", &from, &to, &d);
G[from].push_back(Edge {to, d});
G[to].push_back(Edge {from, d});
}
dijkstra(1);
printf("%d\n", dis2[v]);
return 0;
}