倍增求条
查看原帖
倍增求条
530468
_determination_楼主2023/11/30 17:26
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[100010];
struct edge{
	int u,v,w;
}e[300010];
int cmp(edge p,edge q)
{
	return p.w>q.w;
}
int find(int x)
{
	if(a[x]==x)
	{
		return x;
	}
	return a[x]=find(a[x]);
}
vector<pair<int,int> >t[100010];
int fa[100010][25],mx[100010][25],dep[100010];
bool vis[100010];
void dfs(int x)
{
	vis[x]=1;
	dep[x]=dep[fa[x][0]];
	for ( int i = 0 ; i < t[x].size() ; i++ )
	{
		int v=t[x][i].first,w=t[x][i].second;
		if(v==fa[x][0])
		{
			continue;
		}
		fa[v][0]=x;
		mx[v][0]=w;
		for ( int j = 1 ; j <= 20 ; j++ )
		{
			fa[v][j]=fa[fa[v][j-1]][j-1];
			mx[v][j]=min(mx[fa[v][j-1]][j-1],mx[v][j-1]);
		}
		dfs(v);
	}
}
//---------------倍增lca预处理-------------
int lca(int x,int y)
{
	if(dep[x]<dep[y])
	{
		swap(x,y);
	}
	int ans=0x3f3f3f3f3f3f3f3f;
	int k=20;
	while(dep[x]!=dep[y])
	{
		if(dep[fa[x][k]]>=dep[y])
		{
			ans=min(ans,mx[x][k]);
			x=fa[x][k];
		}
		k--;
	}
	k=20;
	while(fa[x][0]!=fa[y][0])
	{
		if(fa[x][k]!=fa[y][k])
		{
			ans=min(ans,mx[x][k]);
			ans=min(ans,mx[y][k]);
			x=fa[x][k];
			y=fa[y][k];
		}
		k--;
	}
	ans=min(ans,mx[x][0]);
	ans=min(ans,mx[y][0]);
	return ans;
 } 
signed main()
{
	memset(mx,0x3f,sizeof(mx));
	int n,m;
	cin >> n >> m ;
	for ( int i = 1 ; i <= m ; i++ )
	{
		cin >> e[i].u >>e[i].v >> e[i].w;
	}
	sort(e+1,e+1+m,cmp);
	for ( int i = 1 ; i <= n ; i++ )
	{
		a[i]=i;
	}
	for ( int i = 1 ; i <= m ; i++ )
	{
		int u=e[i].u,v=e[i].v,w=e[i].w;
		int fu=find(u),fv=find(v);
		if(fu==fv)
		{
			continue;
		}
		a[fu]=fv;
		t[u].push_back({v,w});
		t[v].push_back({u,w});
	}
	for ( int i = 1 ; i <= n ; i++ )
	{
		if(!vis[i])
		{
			for ( int j = 0 ; j <= 20 ; j++ )
			{
				fa[i][j]=i;
			}
			dfs(i);
		}
	}
	int q;
	cin >> q;
	while(q--)
	{
		int u,v;
		cin >> u >> v;
		if(find(u)!=find(v))
		{
			cout << "-1\n";
			continue;
		}
		cout << lca(u,v) << endl;
	}
	return 0;
} 

shit一般的代码,感觉lca挂了,但是不知道原因。

Link

2023/11/30 17:26
加载中...