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
| #include <bits/stdc++.h> using namespace std; typedef pair<int, int> PII; const int N = 3e5 + 10; int n, m, q; struct Edge { int w; int to, pre; }edge[N]; bool cmp(Edge& x, Edge& y) { return x.w > y.w; } vector<PII> tree[N]; int fa[N]; int find(int x) { if(x != fa[x]) fa[x] = find(fa[x]); return fa[x]; } void kruskal() { for(int i = 1; i <= m; i++) { int fx = find(edge[i].pre), fy = find(edge[i].to); if(fx != fy) { fa[fx] = fy; tree[edge[i].pre].push_back({edge[i].to, edge[i].w}); tree[edge[i].to].push_back({edge[i].pre, edge[i].w}); } } } int dep[N], dp[N][20], cost[N][20], vis[N]; void dfs(int u, int p) { vis[u] = 1; dep[u] = dep[p] + 1; dp[u][0] = p; for(int i = 1; i < 20; i++) { dp[u][i] = dp[dp[u][i - 1]][i - 1]; cost[u][i] = min(cost[u][i - 1], cost[dp[u][i - 1]][i - 1]); } for(auto t: tree[u]) { int child = t.first, c = t.second; if(child != p) { cost[child][0] = c; dfs(child, u); } } } int lca(int x, int y) { int ans = 1e18; if(dep[x] < dep[y]) swap(x, y); int d = dep[x] - dep[y]; for(int i = 0; i < 20; i++) if((1 << i) & d) { ans = min(ans, cost[x][i]); x = dp[x][i]; } if(x == y) return ans; for(int i = 20 - 1; i >= 0; i--) { if(dp[x][i] != dp[y][i]) { ans = min(ans, min(cost[x][i], cost[y][i])); x = dp[x][i], y = dp[y][i]; } } ans = min(ans, min(cost[x][0], cost[y][0])); return ans; } int main() { cin >> n >> m >> q; for(int i = 1; i <= m; i++) cin >> edge[i].pre >> edge[i].to >> edge[i].w; sort(edge + 1, edge + 1 + m, cmp); for(int i = 1; i <= n; i++) fa[i] = i; kruskal(); for(int i = 1; i <= n; i++) if(!vis[i]) dfs(i, 0); while(q--) { int x, y; cin >> x >> y; int fx = find(x), fy = find(y); if(fx != fy) cout << -1 << '\n'; else cout << lca(x, y) << '\n'; } return 0; }
|