【题目链接】
【思路要点】
- 补档博客,无题解。
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 200005 #define INF 1e18 template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } struct Segment_Tree { int n, size, root; int lc[MAXN * 2], rc[MAXN * 2]; long long tag[MAXN * 2]; int new_node() { tag[size] = INF; return size++; } void build(int root, int l, int r) { if (l == r) return; int mid = (l + r) / 2; lc[root] = new_node(); build(lc[root], l, mid); rc[root] = new_node(); build(rc[root], mid + 1, r); } void init(int x) { n = x; size = 0; root = new_node(); build(root, 1, n); } void modify(int root, int l, int r, int ql, int qr, long long value) { if (l == ql && r == qr) { tag[root] = min(tag[root], value); return; } int mid = (l + r) / 2; if (mid >= ql) modify(lc[root], l, mid, ql, min(qr, mid), value); if (mid + 1 <= qr) modify(rc[root], mid + 1, r, max(mid + 1, ql), qr, value); } void modify(int l, int r, long long value) { if (l <= r) modify(root, 1, n, l, r, value); } long long query(int root, int l, int r, int x) { if (l == r) return tag[root]; int mid = (l + r) / 2; if (mid >= x) return min(tag[root], query(lc[root], l, mid, x)); else return min(tag[root], query(rc[root], mid + 1, r, x)); } long long query(int x) { return query(root, 1, n, x); } } ST; struct edge {int dest, len; }; struct info {long long value; int pos, home; }; int n, m, s, t, pred[MAXN], succ[MAXN]; int x[MAXN], y[MAXN], z[MAXN], num[MAXN]; vector <edge> a[MAXN]; vector <int> b[MAXN]; priority_queue <info> Heap; long long dist[MAXN], cist[MAXN]; bool mark[MAXN]; bool operator < (info a, info b) {return a.value > b.value; } bool on_road(int x, int y) { return mark[x] && mark[y] && (succ[x] == y || succ[y] == x); } void work(int pos, int value) { num[pos] = value; for (unsigned i = 0; i < b[pos].size(); i++) if (num[b[pos][i]] == 0) work(b[pos][i], value); } int main() { read(n), read(m); for (int i = 1; i <= m; i++) { read(x[i]), read(y[i]), read(z[i]); a[x[i]].push_back((edge) {y[i], z[i]}); a[y[i]].push_back((edge) {x[i], z[i]}); } read(s), read(t); for (int i = 1; i <= n; i++) dist[i] = cist[i] = INF; dist[s] = 0; Heap.push((info) {0, s, 0}); while (!Heap.empty()) { while (!Heap.empty() && mark[Heap.top().pos]) Heap.pop(); if (Heap.empty()) break; info tmp = Heap.top(); Heap.pop(); mark[tmp.pos] = true; pred[tmp.pos] = tmp.home; for (unsigned i = 0; i < a[tmp.pos].size(); i++) if (tmp.value + a[tmp.pos][i].len < dist[a[tmp.pos][i].dest]) { dist[a[tmp.pos][i].dest] = tmp.value + a[tmp.pos][i].len; Heap.push((info) {dist[a[tmp.pos][i].dest], a[tmp.pos][i].dest, tmp.pos}); } } if (dist[t] == INF) { int q; read(q); for (int i = 1; i <= q; i++) printf("Infinity\n"); return 0; } memset(mark, 0, sizeof(mark)); cist[t] = 0; Heap.push((info) {0, t, 0}); while (!Heap.empty()) { while (!Heap.empty() && mark[Heap.top().pos]) Heap.pop(); if (Heap.empty()) break; info tmp = Heap.top(); Heap.pop(); mark[tmp.pos] = true; for (unsigned i = 0; i < a[tmp.pos].size(); i++) if (tmp.value + a[tmp.pos][i].len < cist[a[tmp.pos][i].dest]) { cist[a[tmp.pos][i].dest] = tmp.value + a[tmp.pos][i].len; Heap.push((info) {cist[a[tmp.pos][i].dest], a[tmp.pos][i].dest, tmp.pos}); } } memset(mark, 0, sizeof(mark)); int pos = t; while (pos) { mark[pos] = true; succ[pred[pos]] = pos; pos = pred[pos]; } int cnt = 0; pos = s; while (pos) { num[pos] = ++cnt; pos = succ[pos]; } for (int i = 1; i <= n; i++) b[pred[i]].push_back(i); for (int i = 1; i <= n; i++) if (num[i]) work(i, num[i]); ST.init(cnt); for (int i = 1; i <= m; i++) if (!on_road(x[i], y[i])) { if (num[x[i]] > num[y[i]]) swap(x[i], y[i]); ST.modify(num[x[i]], num[y[i]] - 1, dist[x[i]] + z[i] + cist[y[i]]); } int q; read(q); for (int i = 1; i <= q; i++) { int x, y; read(x), read(y); if (!on_road(x, y)) printf("%lld\n", dist[t]); else { if (num[x] > num[y]) swap(x, y); long long tmp = ST.query(num[x]); if (tmp == INF) printf("Infinity\n"); else printf("%lld\n", tmp); } } return 0; }