MnZn求助,生成树+lca,10分
查看原帖
MnZn求助,生成树+lca,10分
105865
Jur_Cai楼主2021/8/9 23:08

Rt

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#define INF 0x3f3f3f3f
#define P pair<int,int>
using namespace std;
struct edge {
	int x,y,z;
	bool operator < (const edge b) const {
		return this->z>b.z; 
	}
}a[50005];
int f[10005];
inline int find(int x) {
	if(!f[x]) return x;
	return f[x]=find(f[x]);
}
vector<P> g[10005];
int lg[10005],fa[10005][15],w[10005][15],dep[10005];
bool vis[10005];
void dfs(int x) {
	for(int i=1;i<=lg[dep[x]];i++)
		fa[x][i]=fa[fa[x][i-1]][i-1],w[x][i]=min(w[x][i-1],w[fa[x][i-1]][i-1]);
	for(int i=0;i<g[x].size();i++)
		if(!vis[g[x][i].first]) {
			vis[g[x][i].first]=1;
			dep[g[x][i].first]=dep[x]+1;
			fa[g[x][i].first][0]=x;
			w[g[x][i].first][0]=g[x][i].second;
			dfs(g[x][i].first);
		} 
}
inline int work(int x,int y) {
	if(find(x)!=find(y)) return -1;
	int ans=INF;
	if(dep[x]<dep[y]) swap(x,y);
	while(dep[x]>dep[y]) {
		ans=min(ans,w[x][lg[dep[x]-dep[y]]-1]);
		x=fa[x][lg[dep[x]-dep[y]]-1];
	}
	if(x==y) return ans;
	for(int k=lg[dep[x]]-1;k>=0;k--) 
		if(fa[x][k]!=fa[y][k]) {
			ans=min(ans,min(w[x][k],w[y][k]));
			x=fa[x][k],y=fa[y][k];
		}
	ans=min(ans,min(w[x][0],w[y][0]));
	return ans;
}
int main() {
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++) 
		scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
	sort(a+1,a+m+1);
	for(int i=1;i<=m;i++){
		int x=find(a[i].x),y=find(a[i].y);
		if(x!=y) {
			f[x]=y;
			g[a[i].x].push_back(P(a[i].y,a[i].z));
			g[a[i].y].push_back(P(a[i].x,a[i].z));
		}
	}
	for(int i=1;i<=n;i++) lg[i]=lg[i-1]+(1<<lg[i-1]==1);
	for(int i=1;i<=n;i++)
		if(!vis[i]) {
			dep[i]=1;
			dfs(i);
		}
	int q;
	scanf("%d",&q);
	while(q--){
		int u,v;
		scanf("%d%d",&u,&v);
		cout<<work(u,v)<<endl;
	}
	return 0;
}
2021/8/9 23:08
加载中...