1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| #include <bits/stdc++.h> #define STC static const int N = 500 + 100, M = 1500 + 100, INF = 0x3f3f3f3f; int n, m, Q; struct Edge{ int ne, ver, w; }; namespace Dinic { int cur[N], dep[N], S, T, idx = 0, h[N]; Edge e[M << 2]; void add(int x, int y, int z){ e[idx] = {h[x], y, z}, h[x] = idx++; } void dad(int x, int y, int z){ add(x, y, z), add(y, x, 0); } void init(int _s, int _t) { S = _s, T = _t; for (int i = 0; i < idx; i += 2) e[i].w = (e[i].w + e[i ^ 1].w), e[i ^ 1].w = 0; } bool bfs() { memset(dep, 0, sizeof dep); std::queue<int> q; for (q.push(S), dep[S] = 1, cur[S] = h[S]; !q.empty(); ) { int x = q.front(); q.pop(); for (int i = h[x], y; ~i; i = e[i].ne) if (!dep[y = e[i].ver] && e[i].w) { dep[y] = dep[x] + 1, cur[y] = h[y]; if (y == T) return true; q.push(y); } } return false; } int find(int x, int lim) { if (x == T) return lim; int t, y, flow = 0; for (int i = cur[x]; ~i && flow < lim; i = e[i].ne) { cur[x] = i; if (dep[y = e[i].ver] == dep[x] + 1 && e[i].w) { if (!(t = find(y, std::min(lim - flow, e[i].w)))) dep[y] = -1; e[i].w -= t, e[i ^ 1].w += t, flow += t; } } return flow; } int dinic(int _s, int _t) { init(_s, _t); int res = 0, flow; while (bfs()) while (flow = find(S, INF)) res += flow; return res; } } namespace GHT { const int D = 10; int nd[N], h[N], idx = 0, dep[N], f[N][D], mn[N][D]; std::default_random_engine eee{114514}; Edge e[N << 1]; void add(int x, int y, int z){ e[idx] = {h[x], y, z}, h[x] = idx++; } void build(int l, int r) { if (l == r) return ; STC int tp1[N], tp2[N]; int s, t, flow, ct1 = 0, ct2 = 0; s = nd[l], t = nd[l + 1]; flow = Dinic::dinic(s, t); add(s, t, flow), add(t, s, flow); for (int i = l; i <= r; ++i) (Dinic::dep[nd[i]] ? tp1[++ct1] : tp2[++ct2]) = nd[i]; for (int i = 1; i <= ct1; ++i) nd[i + l - 1] = tp1[i]; for (int i = 1; i <= ct2; ++i) nd[i + l + ct1 - 1] = tp2[i]; build(l, l + ct1 - 1), build(l + ct1, r); } void bfs() { std::queue<int> q; for (q.push(1), dep[1] = 1; !q.empty(); ) { int x = q.front(); q.pop(); for (int i = h[x], y; ~i; i = e[i].ne) if (!dep[y = e[i].ver]) { dep[y] = dep[x] + 1, f[y][0] = x, mn[y][0] = e[i].w; q.push(y); } } for (int j = 1; j < D; ++j) for (int i = 1; i <= n; ++i) { mn[i][j] = std::min(mn[i][j - 1], mn[f[i][j - 1]][j - 1]); f[i][j] = f[f[i][j - 1]][j - 1]; } } void work() { for (int i = 1; i <= n; ++i) nd[i] = i; shuffle(nd + 1, nd + 1 + n, eee); build(1, n), bfs(); } int ask(int x, int y) { int res = INF; if (dep[x] > dep[y]) std::swap(x, y); for (int i = D - 1; i >= 0; --i) if (dep[f[y][i]] >= dep[x]) res = std::min(res, mn[y][i]), y = f[y][i]; if (x == y) return res == INF ? -1 : res; for (int i = D - 1; i >= 0; --i) if (f[x][i] != f[y][i]) { res = std::min(res, std::min(mn[x][i], mn[y][i])); x = f[x][i], y = f[y][i]; } res = std::min(res, std::min(mn[x][0], mn[y][0])); return res == INF ? -1 : res; } } int main() {
memset(Dinic::h, -1, sizeof Dinic::h); memset(GHT::h, -1, sizeof GHT::h); scanf("%d %d", &n, &m), ++n; for (int i = 1, u, v, w; i <= m; ++i) scanf("%d %d %d", &u, &v, &w), Dinic::dad(++u, ++v, w), Dinic::dad(v, u, w); GHT::work(); scanf("%d", &Q); for (int u, v; Q--; printf("%d\n", GHT::ask(++u, ++v))) scanf("%d %d", &u, &v); return 0; }
|