Kruscal重构树5pts求调
查看原帖
Kruscal重构树5pts求调
492030
CityFish楼主2024/5/26 21:18
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 10010;
const int MAXLOG = 16;

struct Edge{
	int to,lim;
};
struct EdgeforKruscal{
	int x,y,lim;
	friend bool operator < (EdgeforKruscal A,EdgeforKruscal B){
		return A.lim > B.lim;
	}
};

int Deep[MAXN],Anc[MAXN][MAXLOG+1];
int N,M,Q;
int fa[MAXN],dis[MAXN];
vector<Edge> es[MAXN];
vector<EdgeforKruscal> esforK;

int GetFa(int x){
	if(fa[x] == x) return x;
	return fa[x] = GetFa(fa[x]);
}

void Kruscal(){
	for(int i = 1;i <= N;i++) fa[i] = i;
	for(auto e : esforK){
		int x = e.x,y = e.y,lim = e.lim;
		if(GetFa(x) != GetFa(y)){
			fa[GetFa(y)] = x;
			es[x].push_back(Edge{y,lim});
			es[y].push_back(Edge{x,lim});
		}
	}
}

void DFS(int x,int fa){
	Anc[x][0] = fa;Deep[x] = Deep[fa] + 1;
	for(int i = 1;i <= MAXLOG;i++){
		Anc[x][i] = Anc[Anc[x][i-1]][i-1];
	}
	for(auto e : es[x]){
		int to = e.to; 
		if(to != fa){
			dis[to] = e.lim;
			DFS(to,x);
		}
	}
}

int Query(int x,int y){
	int ox = x,oy = y;
	int minz = 0x3f3f3f;
	if(Deep[x] < Deep[y]){
		swap(x,y);
	}
	for(int i = MAXLOG;i >= 0;i--){
		if(Deep[Anc[x][i]] >= Deep[y]) minz = min(minz,dis[x]),x = Anc[x][i];
		
	}
	if(x == y) return minz;
	
	for(int i = MAXLOG;i >= 0;i--){
		if(Anc[x][i] != Anc[y][i]) minz = min(minz,dis[x]),x = Anc[x][i],minz = min(minz,dis[y]),y = Anc[y][i];
	}
	minz = min(minz,dis[x]);
	minz = min(minz,dis[y]);
	return minz;
}

int main(){
	cin>>N>>M;
	for(int i = 1;i <= M;i++){
		int x,y,z;cin>>x>>y>>z;
		esforK.push_back(EdgeforKruscal{x,y,z});
	}
	sort(esforK.begin(),esforK.end());
	Kruscal();
	for(int i = 1;i <= N;i++){
		if(GetFa(i) == i) DFS(i,0);
	}
	cin>>Q;
	for(int i = 1;i <= Q;i++){
		int x,y;cin>>x>>y;
		if(GetFa(x) != GetFa(y)){
			cout<<-1<<endl;
		}
		else cout<<Query(x,y)<<endl;
	}
}

2024/5/26 21:18
加载中...