題面c++
注意到有一些限重很低的邊不會被走到。spa
因而考慮建一棵最大生成樹,在生成樹上尋找答案。code
設\(f[i][j]\)表示\(i\)的\(2^j\)級祖先,\(w[i][j]\)表示\(i\)到\(2^j\)級祖先的最大載重。get
那麼咱們在倍增尋找\(\text{LCA}\)時更新答案便可。it
#include <bits/stdc++.h> #define itn int #define gI gi using namespace std; inline int gi() { int f = 1, x = 0; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();} while (c >= '0' && c <= '9') x = x * 10 + (c ^ 48), c = getchar(); return f * x; } const int maxn = 100003; int q, n, m, tot, head[maxn], ver[maxn], edge[maxn], nxt[maxn], fa[maxn][23]; int f[maxn], w[maxn][23], vis[maxn], dep[maxn]; struct Node { int u, v, w; } e[maxn]; inline bool cmp(Node x, Node y) {return x.w > y.w;} int getf(int u) { if (f[u] == u) return u; return f[u] = getf(f[u]); } inline void add(int u, int v, int w) { ver[++tot] = v, nxt[tot] = head[u], edge[tot] = w, head[u] = tot; } inline void get_MST() { for (int i = 1; i <= n; i+=1) f[i] = i; for (int i = 1; i <= m; i+=1) { int U = getf(e[i].u), V = getf(e[i].v); if (U != V) { f[U] = V; add(e[i].u, e[i].v, e[i].w); add(e[i].v, e[i].u, e[i].w); } } } void dfs(int u) { vis[u] = 1; for (int i = head[u]; i; i = nxt[i]) { int v = ver[i], ww = edge[i]; if (vis[v]) continue; dep[v] = dep[u] + 1; fa[v][0] = u; w[v][0] = ww; dfs(v); } } inline int getans(int u, int v) { if (dep[u] > dep[v]) swap(u, v); int uu = 0x3f3f3f3f; for (int i = 20; i >= 0; i-=1) { if (dep[fa[v][i]] >= dep[u]) uu = min(uu, w[v][i]), v = fa[v][i]; } if (u == v) return uu; for (int i = 20; i >= 0; i-=1) { if (fa[u][i] != fa[v][i]) { uu = min(uu, min(w[u][i], w[v][i])); u = fa[u][i], v = fa[v][i]; } } uu = min(uu, min(w[u][0], w[v][0])); return uu; } int main() { //freopen(".in", "r", stdin); //freopen(".out", "w", stdout); n = gi(), m = gi(); for (int i = 1; i <= m; i+=1) { int u = gi(), v = gi(), w = gi(); e[i].u = u, e[i].v = v, e[i].w = w; } sort(e + 1, e + 1 + m, cmp); get_MST(); for (int i = 1; i <= n; i+=1) { if (!vis[i]) { dep[i] = 1; dfs(i); fa[i][0] = i; w[i][0] = 0x3f3f3f3f; } } for (int i = 1; i <= 20; i+=1) for (int j = 1; j <= n; j+=1) fa[j][i] = fa[fa[j][i - 1]][i - 1], w[j][i] = min(w[j][i - 1], w[fa[j][i - 1]][i - 1]); q = gi(); while (q--) { int u = gi(), v = gi(); if (getf(u) != getf(v)) {puts("-1"); continue;} printf("%d\n", getans(u, v)); } return 0; }