P1967 货车运输 [Kruskal 重构树]

传送门 

重构树模板

#include<bits/stdc++.h>
#define N 20050
#define M 50050
using namespace std;
int first[N],next[M],to[M],tot;
struct Node{int u,v,w;}E[M];
bool cmp(Node a,Node b){return a.w>b.w;}
int n,m,q,cnt;
int father[N]; 
int find(int x){return x==father[x]?x:father[x]=find(father[x]);}
int fa[N][20],dep[N],val[N],id[N];
int read(){
	int cnt=0; char ch=0;
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))cnt=cnt*10+(ch-'0'),ch=getchar();
	return cnt;
}

void add(int x,int y){next[++tot]=first[x],first[x]=tot,to[tot]=y;}

void dfs(int u,int ID){
	for(int i=1;i<=16;i++)
		fa[u][i] = fa[fa[u][i-1]][i-1];
	id[u] = ID;
	for(int i=first[u];i;i=next[i]){
		int t=to[i]; fa[t][0] = u; 
		dep[t] = dep[u] + 1; dfs(t,ID);
	}
}
void Kruskal(){
	sort(E+1,E+m+1,cmp); cnt = n;
	for(int i=1;i<=m;i++){
		int x = E[i].u, y = E[i].v;
		int fx = find(x), fy = find(y);
		if(fx!=fy){
			val[++cnt] = E[i].w;
			father[fx] = father[fy] = cnt;
			add(cnt,fx), add(cnt,fy);
		}
	} 
	for(int i=n+1;i<=cnt;i++) if(father[i]==i) 
		dep[i] = 1, dfs(i,i);
}
int lca(int x,int y){
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=16;i>=0;i--)
		if(dep[fa[x][i]] >= dep[y])
			x = fa[x][i];
	if(x==y) return x;
	for(int i=16;i>=0;i--)
		if(fa[x][i]!=fa[y][i]) 
			x=fa[x][i], y=fa[y][i];
	return fa[x][0];
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n*2;i++) father[i] = i;
	for(int i=1;i<=m;i++){
		E[i].u = read(), E[i].v =read(), E[i].w = read();
	}  Kruskal();
	q=read();
	while(q--){
		int x=read(),y=read();
		if(id[x]!=id[y]){printf("-1\n"); continue;}
		int l = lca(x,y); 
		printf("%d\n",val[l]);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/sslz_fsy/article/details/86627236