Kruskal重构树+LCA 60pts TLE求助
查看原帖
Kruskal重构树+LCA 60pts TLE求助
627293
FanMingxuan楼主2024/6/14 17:08

代码如下

#include<bits/stdc++.h>
using namespace std;
const int M = 100005;
const int N = 20005;

namespace Set{
	int f[N];
	
	void init(int n){
		for(int i = 1;i <= n;++ i){
			f[i] = i;
		}
	}
	
	inline int find(int w){
		if(f[w] == w) return w;
		return f[w] = find(f[w]);
	}
	
	inline void merge(int x,int y){
		f[x] = y;
	}
}

namespace Tree{
	int w[N];
	struct edge{
		int v;
		int next;
	}e[N << 1];
	int head[N];
	int cur = 0;
	
	void addedge(int u,int v){
		e[++ cur].v = v;
		e[cur].next = head[u];
		head[u] = cur;
	}
	
	int g[N][20],dep[N];
	bool used[N];
	
	void dfs(int u,int fa){
		used[u] = true;
		dep[u] = dep[fa] + 1;
		g[u][0] = fa;
		for(int k = 1;k <= 16;++ k){
			g[u][k] = g[g[u][k - 1]][k - 1];
		}
		for(int i = head[u];i;i = e[i].next){
			int v = e[i].v;
			if(v == fa) continue;
			dfs(v,u);
		}
	}
	
	int LCA(int x,int y){
		if(Set::find(x) != Set::find(y)) return 0;
		if(x == y) return x;
		if(dep[x] < dep[y]) swap(x,y);
		for(int k = 16;k >= 0;-- k){
			if(dep[g[x][k]] >= dep[y]){
				x = g[x][k];
			}
		}
		if(x == y) return x;
		for(int k = 16;k >= 0;-- k){
			if(g[x][k] != g[y][k]){
				x = g[x][k];
				y = g[y][k];
			}
		}
		return g[x][0];
	}
}

namespace Graph{
	struct edge{
		int u;
		int v;
		int w;
	}e[M];
	int cur = 0;
	
	void addedge(int u,int v,int w){
		e[++ cur].u = u;
		e[cur].v = v;
		e[cur].w = w;
	}
	
	void kruskal(int n){
		Set::init(n << 1);
		sort(e + 1,e + cur + 1,[](const edge& A,const edge& B) -> bool const { return A.w > B.w; });
		int cnt = 0;
		for(int i = 1;i <= cur && cnt < n - 1;++ i){
			int x = Set::find(e[i].u),y = Set::find(e[i].v);
			if(x != y){
				cnt ++;
				Set::merge(x,n + cnt);
				Set::merge(y,n + cnt);
				Tree::addedge(n + cnt,x);
				Tree::addedge(n + cnt,y);
				Tree::w[n + cnt] = e[i].w;
			}
		}
		for(int i = n + 1;i <= (n << 1) - 1;++ i){
			if(!Tree::used[i]) Tree::dfs(i,0);
		}
	}
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n,m;
	cin>>n>>m;
	for(int i = 1;i <= m;++ i){
		int u,v,w;
		cin>>u>>v>>w;
		Graph::addedge(u,v,w);
	}
	Graph::kruskal(n);
	int T;
	cin>>T;
	while(T --){
		int x,y;
		cin>>x>>y;
		int lca = Tree::LCA(x,y);
		if(lca) cout<<Tree::w[lca]<<"\n";
		else cout<<-1<<"\n";
	}
	return 0;
}
2024/6/14 17:08
加载中...