省选专练(学习)Kruskal重构树BZOJ3732: Network

很神奇的东西

%%%XCdalao考完试给我说:我好菜啊:我不会记录边权就开了点

%%%他考场发明了Kruskal重构树

Kruskal重构树的特点是:

由于边权的单调性于是父亲节点权值大于儿子节点

而且只有叶子节点才是真实的节点

Kruskal重构树的性质:

LCA的权就是瓶颈

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int N=2e5+100;
inline void read(int &x){
	x=0;
	char ch=getchar();
	int f=1;
	while(ch<'0'||ch>'9'){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	x*=f;
}
struct Front_star{
	int u,v,w,nxt;
}e[N*4];
int cnt=0;                      
int head[N]={};
void Insert(int u,int v){
	cnt++;
	e[cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
int n,m;
bool cmp(Front_star A,Front_star B){
	return A.w<B.w;
}
int fa[N]={};
int tot;
int st[N][21]={};
int dep[N]={};
void dfs(int u,int fat){
//	cout<<u<<" "<<fat<<'\n';
	st[u][0]=fat;
	for(int i=1;i<=18;i++){
		st[u][i]=st[st[u][i-1]][i-1];
	}
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==fat)continue;
		dep[v]=dep[u]+1;
		dfs(v,u);
	}
}
int GetLCA(int x,int y){
	if(dep[x]<dep[y])swap(x,y);
	for(int i=20;i>=0;i--){
		if(dep[x]-(1<<i)>=dep[y])x=st[x][i];
	}
//	cout<<x<<" "<<y<<'\n';
	if(x==y)return x;
	for(int i=20;i>=0;i--){
		if(st[x][i]!=st[y][i]){
			x=st[x][i];
			y=st[y][i];
		}
	}
	return st[x][0];
}
int val[N]={};
inline int getfa(int x){
	if(fa[x]==x)return x;
	else return fa[x]=getfa(fa[x]);
}
int main(){
//	freopen("BZOJ3732.in","r",stdin);
	read(n);
	int K;
	tot=n;
	read(m);
	read(K);
	for(int i=1;i<=m;i++){
		read(e[i].u);
		read(e[i].v);
		read(e[i].w);
	}
	cnt=m;
	sort(e+1,e+1+m,cmp);
	for(int i=1;i<=2*n;i++)fa[i]=i;
	for(int i=1;i<=m;i++){
//		cout<<e[i].w<<'\n';
		int u=e[i].u;
		int v=e[i].v;
		if(getfa(u)!=getfa(v)){
			tot++;
			Insert(tot,getfa(u));
			Insert(tot,getfa(v));
			fa[getfa(u)]=tot;
			fa[getfa(v)]=tot;
			val[tot]=e[i].w;
		}
	}
	/*for(int i=n+1;i<=tot;i++){
		cout<<val[i]<<'\n';
	}*/
//	cout<<tot<<'\n';
	dfs(tot,0);
	while(K--){
		int A,B;
		read(A);
		read(B);
//		cout<<GetLCA(A,B)<<" ";
		cout<<val[GetLCA(A,B)]<<'\n';
	}
}

猜你喜欢

转载自blog.csdn.net/fcb_x/article/details/81087383