某街区共有R条道路,N个路口。道路可以双向通行。问一号路口到N号路口的次短路的长度是多少。同一条路可以经过多次。
#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
const int MAX_N = 100000 + 50;
const int INF = 1000000000;
int N, R;
struct edge {int to, cost;};
typedef pair <int, int> P; // first 是最短距离,second 是顶点的编号
vector <edge> G[MAX_N];
int dist[MAX_N]; //最短距离
int dist2[MAX_N]; //次短距离
void solve () {
//按照first从小到大的顺序取出值
priority_queue <P, vector <P>, greater <P> > que;
//初始化
fill (dist, dist + N, INF);
fill (dist2, dist2 + N, INF);
dist[0] = 0;
que.push(P(0, 0));
while (!que.empty()) {
//每次取出最小的
P p = que.top(); que.pop();
//定义 v 为定点标号 d 为最短距离
int v = p.second, d = p.first;
//如果当前的次短距离小于最短距离则跳过
if (dist2[v] < d) continue;
for (int i = 0; i < G[v].size(); i ++) {
edge &e = G[v][i];
//d2为此时起点到 i 点的距离
int d2 = d + e.cost;
//保证dist里边储存的是最短距离
if (dist[e.to] > d2) {
swap (dist[e.to], d2);
que.push(P(dist[e.to], e.to));
}
//保证 dist里边储存的d2是次短距离
if (dist2[e.to] > d2 && dist[e.to] < d2) {
dist2[e.to] = d2;
que.push(P(dist2[e.to], e.to));
}
}
}
cout << dist2[N - 1] << endl;
}
int main() {
cin >> N >> R;
edge nn;
int s;
for (int i = 0; i < R; i++) {
cin >> s >> nn.to >> nn.cost;
// 保证 0 ~ N - 1
s--;
nn.to--;
G[s].push_back(nn);
swap (s, nn.to);
G[s].push_back(nn);
}
solve ();
return 0;
}