https://www.luogu.org/problem/show?pid=1186
考虑暴力,枚举图上每一条边删去后跑Dijkstra,取M次的最大值。
仔细想想就会发现删除最短路以外的边对最短路毫无影响,于是先跑出最短路,然后枚举最短路上的每一条边删去后跑Dijkstra,取这几次的最大值。
#include <iostream> #include <vector> #include <queue> #include <cstring> #define maxn 1005 using namespace std; const int inf = 0x3f3f3f3f; int n, m; struct edge { int from, to, weight; }; vector<edge> e; vector<int> g[maxn]; bool known[maxn]; int dist[maxn], front[maxn]; typedef pair<int, int> pin; priority_queue<pin, vector<pin>, greater<pin>> pq; void dijkstra() { for (int i = 1; i <= n; ++i) { dist[i] = inf; known[i] = false; front[i] = -1; } while (!pq.empty()) pq.pop(); dist[1] = 0; pq.push(make_pair(dist[1], 1)); while (!pq.empty() && !known[n]) { int x = pq.top().second; pq.pop(); if (known[x]) continue; known[x] = true; for (int i = 0; i < g[x].size(); i++) { edge &ed = e[g[x][i]]; if (!known[ed.to] && dist[ed.to] > dist[x] + ed.weight) { dist[ed.to] = dist[x] + ed.weight; front[ed.to] = g[x][i]; pq.push(make_pair(dist[ed.to], ed.to)); } } } } vector<int> path; int main() { cin >> n >> m; int u, v, w; for (int i = 1; i <= m; i++) { cin >> u >> v >> w; e.push_back((edge){u, v, w}); g[u].push_back(e.size() - 1); e.push_back((edge){v, u, w}); g[v].push_back(e.size() - 1); } dijkstra(); for (int i = front[n]; i != -1; i = front[e[i].from]) path.push_back(i); int ans = dist[n]; for (int i = 0; i < path.size(); i++) { w = e[path[i]].weight; e[path[i]].weight = e[path[i] ^ 1].weight = inf; dijkstra(); if (dist[n] != inf) ans = max(ans, dist[n]); e[path[i]].weight = e[path[i] ^ 1].weight = w; } cout << ans; return 0; }