48分求调
查看原帖
48分求调
375241
SunSkydp楼主2022/7/8 11:31

常规方法:最小生成树+LCA

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
int n, m, q, k, fa[MAXN], dep[MAXN], f[MAXN][22], lg[MAXN], maxn[MAXN][22];
bool c[MAXN];
struct node{
	int u, l;
};
struct edge{
	int u, v, l;
}e[300005];
bool cmp(edge x, edge y) {
	return x.l < y.l;
}
vector<node> g[MAXN];
void init() {
	for (int i = 1; i <= n; i++) fa[i] = i;
}
int find(int x) {
	return fa[x] == x ? fa[x] : (fa[x] = find(fa[x]));
}
void dfs(int to, int fa) {
	for(int i = 0; i < g[to].size(); i++) {
		if(g[to][i].u != fa) {
			dep[g[to][i].u] = dep[to] + 1;
			f[g[to][i].u][0] = to;
			maxn[g[to][i].u][0] = g[to][i].l;
			dfs(g[to][i].u, to);
		}
	}
}
int lca(int x, int y) {
	int ans = 0;
	if(find(x) != find(y)) return -1;
	if(dep[x] < dep[y]) swap(x, y);
	while(dep[x] > dep[y]) {
		ans = max(ans, maxn[x][lg[dep[x] - dep[y]] - 1]);
		x = f[x][lg[dep[x] - dep[y]] - 1];
	}
	if(x == y) return ans;
	for(int i = lg[dep[x]] - 1; i >= 0; i--) {
	    if(f[x][i] != f[y][i]) {
	    	ans = max(ans, max(maxn[x][i], maxn[y][i]));
	    	x = f[x][i], y = f[y][i];
		}
	}
	ans = max(ans, max(maxn[x][0], maxn[y][0]));
	return ans;
}
int main() {
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i++) scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].l);
	init();
	sort(e + 1, e + m + 1, cmp);
	for(int i = 1; i <= m; i++) {
		int x = find(e[i].u), y = find(e[i].v);
		if(x != y) {
			fa[x] = y;
			g[e[i].u].push_back((node){e[i].v, e[i].l});
			g[e[i].v].push_back((node){e[i].u, e[i].l});
			//ru[e[i].]
			k++;
			if(k == n - 1) break;
		}
	}
	for(int i = 1; i <= n; i++) lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
	for(int i = 1; i <= n; i++) {
		if(!c[fa[i]] && fa[i] != 1) {
			dfs(fa[i], 0);
			c[fa[i]] = true;
			c[i] = true;
	    } 
	}
	for(int i = 1; i <= 20; i++) {
		for(int to = 1; to <= n; to++) {
			f[to][i] = f[f[to][i - 1]][i - 1];
			maxn[to][i] = max(maxn[to][i - 1], maxn[f[to][i - 1]][i - 1]);
		}
	}
	scanf("%d", &q);
	while(q--) {
		int a, b;
		scanf("%d%d", &a, &b);
		if(find(a) != find(b)) puts("impossible\n");
		else printf("%d\n", lca(a, b));
	}
	return 0;
}
2022/7/8 11:31
加载中...