mxqz30pts WA
查看原帖
mxqz30pts WA
724676
Iwara_qwq楼主2022/7/23 13:02
#include<bits/stdc++.h>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<string.h>
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
using namespace std;
const ll INF=0x7f7f7f7f7f,inf=0x3f3f3f3f3f;
namespace Yorihime_Nao{
	template<class T> T MAX(T x,T y){
		return x>y?x:y;
	}
	template<class T,class ... Arg> T MAX(T x,T y,Arg ... arg){
		return MAX(x>y?x:y,arg...);
	}
	template<class T> T MIN(T x,T y){
		return x<y?x:y;
	}
	template<class T,class ... Arg> T MIN(T x,T y,Arg ... arg){
		return MIN(x<y?x:y,arg...);
	}
	template<class T> T lowbit(T x){
		return x&-x;
	}
	template<class T> void SWAP(T &x,T &y){
		x^=y^=x^=y;
		return;
	}
}
using namespace Yorihime_Nao;
const ll MAXN=1e4+5,MAXM=5e4+5; 
ll n,m,x,y,z,q;
struct edge{
	ll u,v,w,nxt;
	bool operator < (const edge &oth)const{
		return w>oth.w;
	}
};
edge e[MAXM],tree[MAXN<<1];
ll edge_num,head[MAXN],tree_cnt,tree_head[MAXN];
void add_edge(ll From,ll To,ll Len){
	edge_num++;
	e[edge_num].u=From;
	e[edge_num].v=To;
	e[edge_num].w=Len;
	e[edge_num].nxt=head[From];
	head[From]=edge_num;
	return;
}
void add_tree(ll From,ll To,ll Len){
	tree_cnt++;
	tree[tree_cnt].u=From;
	tree[tree_cnt].v=To;
	tree[tree_cnt].w=Len;
	tree[tree_cnt].nxt=tree_head[From];
	tree_head[From]=tree_cnt;
	return;
}
ll _fa[MAXN];
ll Find(ll now){
	return _fa[now]==now?now:_fa[now]=Find(_fa[now]);
}
void kruskal(){
	for(int i=1;i<=n;i++)_fa[i]=i;
	sort(e+1,e+1+edge_num);
	ll cnt=0;
	for(int i=1;i<=edge_num;i++){
		ll f_u=Find(e[i].u),f_v=Find(e[i].v);
		if(f_u==f_v)continue;
		cnt++;
		_fa[f_u]=f_v;
		add_tree(e[i].u,e[i].v,e[i].w);
		add_tree(e[i].v,e[i].u,e[i].w);
		if(cnt==n-1)break;
	}
	return;
}
ll deep[MAXN],fa[MAXN][25],sw[MAXN][25];
bool vis[MAXN];
void pre(ll now,ll father){
	if(vis[now])return;
	vis[now]=1;
	deep[now]=deep[father]+1;
	for(int i=1;i<=20;i++)fa[now][i]=fa[fa[now][i-1]][i-1];
	for(int i=1;i<=20;i++)sw[now][i]=MIN(sw[now][i-1],sw[fa[now][i-1]][i-1]);
	for(int i=tree_head[now];i;i=tree[i].nxt){
		if(tree[i].v==father||vis[tree[i].v])continue;
		sw[tree[i].v][0]=tree[i].w;
		fa[tree[i].v][0]=now;
		pre(tree[i].v,now);
	}
}
ll solve(ll p1,ll p2){
	if(deep[p1]<deep[p2])SWAP(p1,p2);
	ll ans=INF;
	for(int i=20;i>=0;i--)if(deep[fa[p1][i]]>=deep[p2])ans=MIN(ans,sw[p1][i]),p1=fa[p1][i];
//	cout<<p1<<" "<<p2<<endl;
	if(p1==p2)return ans;
	for(int i=20;i>=0;i--){
		if(fa[p1][i]!=fa[p2][i]){
			ans=MIN(ans,sw[p1][i],sw[p2][i]);
			p1=fa[p1][i];
			p2=fa[p2][i];
		} 
//		cout<<p1<<" "<<p2<<endl;
	}
	return MIN(ans,sw[p1][0],sw[p2][0]);
}
int main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%lld%lld%lld",&x,&y,&z);
		add_edge(x,y,z);
		add_edge(y,x,z);
	}
	kruskal();
//	for(int i=1;i<=n;i++)for(int j=0;j<=20;j++)sw[i][j]=INF;
	for(int i=1;i<=n;i++)if(!vis[i])pre(i,0);
	scanf("%lld",&q);
	for(int i=1;i<=q;i++){
		scanf("%lld%lld",&x,&y);
		if(Find(x)!=Find(y)){
			printf("-1\n");
			continue;
		}
		printf("%lld\n",solve(x,y));
	}
	return 0;
}

2022/7/23 13:02
加载中...