1026 - 最小瓶颈路 - Network(BZOJ3732)

版权声明:虽然我只是个小蒟蒻但转载也请注明出处哦 https://blog.csdn.net/weixin_42557561/article/details/83419062

传送门

分析

各路大佬都用Kruskal重构树在搞
小蒟蒻就先打一个简单的最小瓶颈路
求两点之间路径上的最大边权最小
显然,为了使最大的边权最小
我们就用边权最小的边将整个图联通(最小生成树)
那么此时最小瓶颈路肯定在这颗最小生成树上
我们就树上 l c a lca
维护 m a x n [ x ] [ i ] maxn[x][i] 表示从 x x 开始向上走 2i 步 这段距离的最大值
更新的话,和 f a [ i ] [ j ] fa[i][j] 的更新一样
然后就完啦~~~


未完待续……
可能过几个小时就会更上Kruskal重构树的做法啦


Code

#include<bits/stdc++.h>
#define N 16009
#define M 100009
#define in read()
using namespace std;
inline int read(){
	char ch;int f=1,res=0;
	while((ch=getchar())<'0'||ch>'9') if(ch=='-') f=-1;
	while(ch>='0'&&ch<='9'){
		res=(res<<3)+(res<<1)+ch-'0';
		ch=getchar();
	}
	return f==1?res:-res;
}
int n,m,q;
int nxt[M<<1],head[N],cnt=0;
int mst[M<<1],anc[N];
int fa[N][25],maxn[N][25],dep[N];
struct node{int u,v,w,id;}p[M<<1];
void add(int x,int y,int z){
	nxt[++cnt]=head[x];head[x]=cnt;
	p[cnt].u=x;p[cnt].v=y;
	p[cnt].w=z;
}
bool cmp(const node &a,const node &b){return a.w<b.w;}
int getfa(int x){return x==anc[x]?x:anc[x]=getfa(anc[x]);}
int Nxt[M<<1],Head[M<<1],to[M<<1],Cnt=0,w[M<<1];
void new_add(int x,int y,int z){
	Nxt[++Cnt]=Head[x];Head[x]=Cnt;to[Cnt]=y;w[Cnt]=z;
}
void dfs(int u,int fu){
	fa[u][0]=fu;dep[u]=dep[fu]+1;
	for(int e=Head[u];e;e=Nxt[e]){
		int v=to[e];
		if(v==fu) continue;
		maxn[v][0]=w[e];
		dfs(v,u);
	}
}
inline int solve(int x,int y){
	if(dep[x]<dep[y]) swap(x,y);
	int res=-1;
	for(int i=20;i>=0;--i){
		if(dep[fa[x][i]]>=dep[y]){
			res=max(res,maxn[x][i]);	
			x=fa[x][i];
		}
	}
	if(x==y) return res;
	for(int i=20;i>=0;--i){
		if(fa[x][i]!=fa[y][i]){
			res=max(max(maxn[x][i],maxn[y][i]),res);
			x=fa[x][i];y=fa[y][i];
		}
	}
	res=max(max(maxn[x][0],maxn[y][0]),res);
	return res;
}
int main(){
	memset(maxn,128,sizeof(maxn));
	n=in;m=in;q=in;
	int i,j,k,x,y,z;
	for(i=1;i<=m;++i){
		x=in;y=in;z=in;
		add(x,y,z);//其实这个时候完全不用建图,只需要在结构体里赋值即可
		//但重点是!我懒得改了 
	}
	sort(p+1,p+m+1,cmp);
	for(i=1;i<=n;++i) anc[i]=i;
	int num=0;
	for(i=1;i<=m;++i){
		int x=p[i].u,y=p[i].v;
		int fx=getfa(x),fy=getfa(y);
		if(fx!=fy){
			num++;
			anc[fx]=fy;
			new_add(fx,fy,p[i].w);
			new_add(fy,fx,p[i].w);
			if(num==n-1) break;
		}
	}
	dfs(1,0);
	for(j=1;j<=20;++j)
		for(i=1;i<=n;++i)
		{
			fa[i][j]=fa[fa[i][j-1]][j-1];
			maxn[i][j]=max(maxn[fa[i][j-1]][j-1],maxn[i][j-1]);
		}	
	for(i=1;i<=q;++i){
		x=in;y=in;
		printf("%d\n",solve(x,y));
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42557561/article/details/83419062