最小生成树 + 最近公共祖先10pts悬关求调qwq
查看原帖
最小生成树 + 最近公共祖先10pts悬关求调qwq
1011598
chunyangrong楼主2024/7/14 22:30

rt
我真的改不下去了qwq

#include <bits/stdc++.h>
#include <vector>
using namespace std;
const int N = 5e5 + 10;

int n, m, q, f[N];
int dep[N], minn[N][50], fa[N][50];
vector<pair<int, int> > l[N];

struct jgt{
	int x, y, z;
}a[N];

bool cmp(jgt a, jgt b){
	return a.z > b.z;
}

int find(int x){
	return x == f[x] ? x : x = f[x] = find(f[x]);
}

void merge(int x, int y){
	int fx = find(x), fy = find(y);
	f[fy] = fx;
}

bool check(int x, int y){
	int fx = find(x), fy = find(y);	
	if(fx != fy){
		f[fy] = fx;
		return true;
	}
	return false;
}

void Kruskal(){
	sort(a + 1, a + 1 + m, cmp);
	for(int i = 1; i <= m; i++){
		if(check(a[i].x, a[i].y)){
			merge(a[i].x, a[i].y);
			l[a[i].x].push_back(make_pair(a[i].y, a[i].z));
			l[a[i].y].push_back(make_pair(a[i].x, a[i].z));
		}
	}
}

void dfs(int x, int fx, int awa){
	fa[x][0] = fx;
	dep[x] = dep[fx] + 1;
	minn[x][0] = awa;
	for(int i = 1; i <= __lg(dep[x]); i++){
		fa[x][i] = fa[fa[x][i - 1]][i - 1];
		minn[x][i] = min(minn[x][i - 1], minn[fa[x][i - 1]][i - 1]);			
	}
	for(int i = 0; i < l[x].size(); i++){
		if(l[x][i].first != fx){
//			cout << "qwq " << l[x][i].first << " " << l[x][i].second << "\n";
			dfs(l[x][i].first, x, l[x][i].second);
		}
	}
}

int lca(int x, int y){
	int ans = 0x7fffffff;
	if(dep[x] < dep[y])
		swap(x, y);
	while(dep[x] > dep[y]){
		ans = min(ans, minn[x][__lg(dep[x] - dep[y])]);
		x = fa[x][__lg(dep[x] - dep[y])];		
	}
	if(x == y)
		return ans;
	for(int i = __lg(dep[x]); i; i--){
		if(fa[x][i] != fa[y][i]){
			ans = min(ans, min(minn[x][i], minn[y][i]));
			x = fa[x][i];
			y = fa[y][i];
		}
	}
	return min(ans, min(minn[x][0], minn[y][0]));
}

int main(){
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i++)
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
	for(int i = 1; i <= n; i++)
		f[i] = i;
	Kruskal();
	for(int i = 1; i <= n; i++)
		if(!dep[i])
			dfs(i, 0, 0);
	scanf("%d", &q);
	while(q--){
		int u, v;
		scanf("%d%d", &u, &v);
		if(check(u, v))
			printf("-1\n");
		else
			printf("%d\n", lca(u, v));
	}
	return 0;
}
2024/7/14 22:30
加载中...