求助15pts,最大生成树
查看原帖
求助15pts,最大生成树
320652
jqsh楼主2023/8/23 20:32

RT,逻辑是构建最大生成树然后求LCA,求dalao帮助

#include<bits/stdc++.h>
using namespace std;
int n,m,q,head[800001],tot=1,ans[800001],color[800001],dmax[800001],f[800001],d[800001];
vector<int>son[800001];
priority_queue< pair<int,pair<int,int> > >p;
struct Node{
	int To,Next,val;
}e[800001];
struct ASK{
	int x,y,num;
}Q[800001];
void add(int x,int y,int z){
	e[++tot].Next=head[x];
	e[tot].To=y;
	e[tot].val=z;
	head[x]=tot;
	return;
}
void Find(int t){
	while(!p.empty()) p.pop();
	p.push(make_pair(INT_MAX,make_pair(t,0)));
	while(!p.empty()){
		int now=p.top().second.first,nowf=p.top().second.second,nowd=p.top().first;
		p.pop();
		if(color[now]) continue;
		color[now]=t;
		f[now]=nowf;
		for(int i=head[now];i;i=e[i].Next){
			int To=e[i].To,v=min(nowd,e[i].val);
			if(!color[To])
				p.push(make_pair(v,make_pair(To,now)));
		}
	}
	return;
}
void pre(int t,int s){
	d[t]=s;
	for(int i=0;i<son[t].size();i++)
		pre(son[t][i],s+1);
	return;
}
void check(int x,int y,int t){
	if(color[x]!=color[y]){
		ans[t]=-1;
		return;
	}
	if(d[x]<d[y]) swap(x,y);
	int nowans=INT_MAX;
	while(d[x]>d[y]){
		nowans=min(nowans,dmax[x]);
		x=f[x];
	}
	while(x!=y){
		nowans=min(nowans,dmax[x]);
		nowans=min(nowans,dmax[y]);
		x=f[x];y=f[y];
	}
	ans[t]=nowans;
	return;
}
int main(){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		int x,y,z;
		scanf("%d %d %d",&x,&y,&z);
		add(x,y,z);
		add(y,x,z);
	}
	scanf("%d",&q);
	for(int i=1;i<=n;i++)
		if(!f[i])
			Find(i);
	for(int i=1;i<=n;i++) son[f[i]].push_back(i);
	for(int i=1;i<=n;i++)
		for(int j=head[i];j;j=e[j].Next)
			if(e[j].To==f[i])
				dmax[i]=max(dmax[i],e[j].val);
	for(int i=1;i<=n;i++)
		if(color[i]==i)
			pre(i,1);
	for(int i=1;i<=q;i++){
		scanf("%d %d",&Q[i].x,&Q[i].y);
		check(Q[i].x,Q[i].y,i);
		printf("%d\n",ans[i]);
	}
	return 0;
}
2023/8/23 20:32
加载中...