生成树+LCA 10pts求调
查看原帖
生成树+LCA 10pts求调
363815
LiangE楼主2024/10/7 11:45

rt

#include<bits/stdc++.h>
using namespace std;
const int MAXN=5e4+5;
int n,m,q;
struct node{
	int from,to,len;
	friend bool operator <(node a,node b){
		return a.len<b.len;
	}
};
vector<node>E[MAXN];
priority_queue<node>E1;
int faa[MAXN];
int buc[MAXN];
int find(int x){
	return (faa[x]==x?x:(faa[x]=find(faa[x]))); 
}
inline int MIN(int a,int b){
	return (a<b?a:b);
}
inline void SWAP(int&a,int&b){
	int t=a;
	a=b;
	b=t;
}
int dep[MAXN];
int fa[MAXN][15];
int len[MAXN][15];
int lg[MAXN];
void init(int u,int f){
	dep[u]=dep[f]+1;
	fa[u][0]=f;
	for(int i=0;i<E[u].size();i++){
		if(E[u][i].to==f) continue;
		len[E[u][i].to][0]=E[u][i].len;
		init(E[u][i].to,u);
	}
}
int solve(int x,int y){
	if(dep[x]<dep[y]) SWAP(x,y);
	int res=0x3f3f3f3f;
	while(dep[x]!=dep[y]){
		res=MIN(res,len[x][lg[dep[x]-dep[y]]]);
		x=fa[x][lg[dep[x]-dep[y]]];
	}
	if(x==y) return res;
	int i=14;
	while(fa[x][0]!=fa[y][0]){
		if(fa[x][i]!=fa[y][i]){
			x=fa[x][i];
			y=fa[y][i];
			res=MIN(res,len[x][i]);
			res=MIN(res,len[y][i]);
		}
		i--;
	}
	if(fa[x][0]==0) return -1;
	res=MIN(res,len[x][0]);
	res=MIN(res,len[y][0]);
	return res;
}
int main(){
	memset(len,0x3f3f,sizeof(len));
	for(int i=2;i<MAXN;i++) lg[i]=lg[i>>1]+1;
	scanf("%d%d",&n,&m);
	node tmp;
	for(int i=1;i<=n;i++) faa[i]=i;
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&tmp.from,&tmp.to,&tmp.len);
		E1.push(tmp);
	}
	while(!E1.empty()){
		tmp=E1.top();
		E1.pop();
		if(find(tmp.from)==find(tmp.to)) continue;
		faa[find(tmp.from)]=find(find(tmp.to));
		E[tmp.from].push_back(tmp);
		SWAP(tmp.from,tmp.to);
		E[tmp.from].push_back(tmp);
	}
	for(int i=1;i<=n;i++){
		if(!buc[find(i)]){
			buc[faa[i]]=1;
			init(i,0);
		}
	}
	
	for(int d=1;d<=14;d++){
		for(int i=1;i<=n;i++){
			fa[i][d]=fa[fa[i][d-1]][d-1];
			len[i][d]=MIN(len[i][d-1],len[fa[i][d-1]][d-1]);
		}
	}
	scanf("%d",&q);
	int x,y;
	for(int i=1;i<=q;i++){
		scanf("%d%d",&x,&y);
		printf("%d\n",solve(x,y));
	}
	return 0;
}
2024/10/7 11:45
加载中...