20pts求调,Kru+倍增
查看原帖
20pts求调,Kru+倍增
370648
柠檬布丁吖楼主2022/8/19 20:36
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<map>
#include<queue>
#include<algorithm>
//#define int long long

using namespace std;

//末日在干什么,有没有空,可以来刷题吗
inline int read() {
	int ret=0,f=1;
	char c=getchar();
	for(; c<'0'||c>'9'; c=getchar()) if(c=='-') f=-f;
	for(; c>='0'&&c<='9'; c=getchar()) ret=ret*10+c-'0';
	return ret*f;
}
const int maxn=1e5+10;
int n,m;
struct EDGE {
	int x,y,z;
} E[maxn*2];
bool cmp(const EDGE &a,const EDGE &b) {
	return a.z>b.z;
}
int f[maxn];
inline void init(int n) {
	for(int i=1; i<=n; i++) {
		f[i]=i;
	}
}

int Find(int x) {
	if(x==f[x]) return x;
	else return f[x]=Find(f[x]);
}
struct edge {
	int to,ne,num;
} e[maxn*2];
int head[maxn],tot;
inline void add(int x,int y,int z) {
	tot++;
	e[tot].to=y;
	e[tot].ne=head[x];
	e[tot].num=z;
	head[x]=tot;
}//lik=head ter=to nxt=ne w=z
int fa[100005][21],d[maxn][21],dep[maxn],inf=0x3f3f3f3f;
inline void dfs(int p,int las) {
	for(int i=1; (1<<i) <= dep[p] ; i++) { //倍增
		fa[p][i]=fa[fa[p][i-1]][i-1];
		d[p][i]=min(d[p][i-1],d[fa[p][i-1]][i-1]);
	}

	for(int i=head[p]; i; i=e[i].ne) {
		if(e[i].to!=las) {
			dep[e[i].to]=dep[p]+1;
			fa[e[i].to][0]=p;
			d[e[i].to][0]=e[i].num;
			dfs(e[i].to,p);
		}
	}
}

int query(int x,int y) {
	if(dep[x]<dep[y]) swap(x,y);
	int res=dep[x]-dep[y],ret=inf;
	for(int i=20; i>=0; i--) {
		if((res>>i)&1) {
			ret=min(ret,d[x][i]);
			x=fa[x][i];
		}
	}
	if(x==y) {
		return ret;
	}
	for(int i=20; i>=0; i--) {
		if(fa[x][i]!=fa[y][i]) {
			ret=min(ret,min(d[x][i],d[y][i]));
			x=fa[x][i],y=fa[x][y];
		}
	}
	return min(ret,min(d[x][0],d[y][0]));
}

signed main(void) {

//	long long int ans=1u/2;
//	printf("%lld\n",ans);

	n=read(),m=read();

	for(int i=1; i<=m; i++) {
		E[i].x=read();
		E[i].y=read();
		E[i].z=read();
	}
	sort(E+1,E+1+m,cmp);
	init(n);
	for(int i=1; i<=m; i++) {
		int _x=Find(E[i].x),_y=Find(E[i].y);
		if(_x==_y) continue;
		add(_x,_y,E[i].z);
		add(_y,_x,E[i].z);
		f[_x]=_y;
	}
	for(int i=1; i<=n; i++) {
		if(Find(i)==i) dfs(i,0);
	}

	int Q,u,v;
	Q=read();
	for(int i=1; i<=Q; i++) {
		u=read(),v=read();
		if(Find(u)!=Find(v)) {
			printf("-1\n");
			continue;
		}

		printf("%d\n",query(u,v));
	}

	return 0;
}
2022/8/19 20:36
加载中...