求助,几乎要和题解一模一样了,回复必关
查看原帖
求助,几乎要和题解一模一样了,回复必关
931707
017_007楼主2023/6/29 13:23
#include<bits/stdc++.h>
using namespace std;
inline int read(){
	   int x=0,f=1;char s=getchar();
	   while (s>'9'||s<'0'){
			 if (s=='-') f=-f;
			 s=getchar();
	   }
	   while (s>='0'&&s<='9'){
			 x=x*10+s-'0';
			 s=getchar();
	   }
	   return x*f;
}
const int N = 1e4+10;
const int M = 5e4+10;
const int INF = 0x7f7f7f7f;
int n,m,fa[N][21],F[N],mmin[N][21],first[N],cnt,sum,q,dep[N];
struct node{
	int u,v,w;
}b[M];
struct edge{
	int to,nxt,w;
}edges[M*2];
bool d[N];
bool cmp(const node &a,const node &b) {
	return a.w>b.w;
}
int get(int x) {
	if (x==F[x]) return x;
	else return F[x]=get(F[x]);
}
void add(int u,int v,int w) {
	edges[++cnt].to=v;
	edges[cnt].nxt=first[u];
	first[u]=cnt;
	edges[cnt].w=w;
}
void dfs(int root) {
	d[root]=true;
	for (int t=first[root];t;t=edges[t].nxt) {
		int h=edges[t].to;
		if (d[h]) continue;
		dfs(h);
		dep[h]=dep[root]+1;
		mmin[h][0]=edges[t].w;
		fa[h][0]=root;
	}
	return;
}
int LCA(int x,int y) {
	int d1=x,d2=y,ans=INF;
	if (dep[d1]<dep[d2]) swap(d1,d2);
	if (dep[d1]>dep[d2]) {
		int t=dep[d1]-dep[d2];
		int h=log2(t);
		for (int i=h;i>=0;--i) {
			if (t>=(1<<i)) ans=min(ans,mmin[d1][i]),t-=(1<<i),d1=fa[d1][i];
		}
	}
	int h=log2(dep[d1]);
	for (int i=h;i>=0;--i) {
		if (fa[d1][i]!=fa[d2][i]&&fa[d1][i]!=0&&fa[d2][i]!=0) {
			ans=min(ans,min(mmin[d1][i],mmin[d2][i]));
			d1=fa[d1][i];d2=fa[d2][i];
		}
	}
	ans=min(ans,min(mmin[d1][0],mmin[d2][0]));
	return ans;
}
int main(){
	n=read();m=read();
	for (int i=1;i<=m;++i) 
		b[i].u=read(),b[i].v=read(),b[i].w=read();
	sort(b+1,b+1+m,cmp);
	for (int i=1;i<=n;++i) F[i]=i;
	for (int i=1;i<=m;++i) {
		int x=get(b[i].u),y=get(b[i].v);
		if (x==y) continue;
		F[x]=y;
		add(b[i].u,b[i].v,b[i].w);
		add(b[i].v,b[i].u,b[i].w);
		sum++;
		if (sum==n-1) break;
	}
	for (int i=1;i<=n;++i) {
		if (F[i]==i) {
			dfs(i);
			fa[i][0]=i;
			mmin[i][0]=INF;
		}
	}
	for (int i=1;i<=log2(n);++i) {
		for (int j=1;j<=n;++j) 
			fa[j][i]=fa[fa[j][i-1]][i-1],mmin[j][i]=min(mmin[fa[j][i-1]][i-1],mmin[j][i-1]);
	}
	q=read();
	for (int i=1;i<=q;++i) {
		int x,y;
		x=read();y=read();
		if (get(x)!=get(y)) printf("-1\n");
		else printf("%d\n",LCA(x,y));
	}
	return 0;
}
2023/6/29 13:23
加载中...