bzoj3732-Network【Kruskal重构树模板】

正题

题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3732


题目大意

一张图,每次询问两个点,求这两个点之间路径的最大值的最小是多少。


解题思路

构造一颗 K r u s k a l Kruskal 重构树然后就是模板了。


c o d e code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e5+10;
struct node{
	int x,y,w; 
}e[N];
struct edge_node{
	int to,next;
}a[N];
int n,m,k,tot,cnt,root,ls[N],val[N];
int top[N],dep[N],siz[N],son[N],fa[N];
void addl(int x,int y)
{
	a[++tot].to=y;
	a[tot].next=ls[x];
	ls[x]=tot;
}
bool cmp(node x,node y)
{return x.w<y.w;}
int find(int x)
{return (fa[x]==x)?x:(fa[x]=find(fa[x]));}
void dfs1(int x)
{
	for(int i=ls[x];i;i=a[i].next){
		int y=a[i].to;
		if(y==fa[x]) continue;
		dep[y]=dep[x]+1;fa[y]=x;
		dfs1(y);siz[x]+=siz[y];
		if(siz[y]>siz[son[x]])
			son[x]=y;
	}
}
void dfs2(int x)
{
	if(son[x]){
		top[son[x]]=top[x];
		dfs2(son[x]);
	}
	for(int i=ls[x];i;i=a[i].next){
		int y=a[i].to;
		if(y==fa[x]||y==son[x]) continue;
		top[y]=y;dfs2(y);
	}
}
int LCA(int x,int y)
{
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		x=fa[top[x]];
	}
	if(dep[x]<dep[y]) return x;
	else return y;
}
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=m;i++)
		scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
	for(int i=1;i<=n+m;i++)
		fa[i]=i;
	sort(e+1,e+1+m,cmp);cnt=n;
	for(int i=1;i<=m;i++){
		int fx=find(e[i].x),fy=find(e[i].y);
		if(fx!=fy){
			fa[fy]=fa[fx]=++cnt;
			addl(cnt,fx);addl(cnt,fy);
			addl(fx,cnt);addl(fy,cnt);
			val[cnt]=e[i].w;
		}
	}
	root=find(1);
	dfs1(root);top[root]=root;dfs2(root);
	for(int i=1;i<=k;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		printf("%d\n",val[LCA(x,y)]);
	}
}
发布了867 篇原创文章 · 获赞 55 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/Mr_wuyongcong/article/details/103841702