wr10 lca生成树解法 求助qwq
查看原帖
wr10 lca生成树解法 求助qwq
302750
Main_WF楼主2021/7/22 10:37
#include<bits/stdc++.h>
using namespace std;
const int maxn=10010;
const int inf=10010000;

struct node
{
	int u,v,nxt,w;
	bool operator <(const node &t)const
	{
		return w>t.w;
	}
}e[100010];int k,head[maxn];

int n,m,q,color;
int depth[maxn],f[maxn][20],lg[maxn],w[maxn][20],ro[maxn],belong[maxn];
bool vis[maxn];
node ex[50010];


void add(int u,int v,int w)
{e[++k].v=v;e[k].w=w;e[k].u=u;e[k].nxt=head[u];head[u]=k;}

template<class type>const void read(type &in)
{
	in = 0;
	char ch = getchar();
	while(ch < 48 || ch > 57)ch = getchar();
	while(ch > 47 && ch < 58)
	{
		in = (in << 1) + (in << 3) + (ch & 15);
		ch = getchar();
	}
}

int find(int v)
{
	if(v!=ro[v])ro[v]=find(ro[v]);
	return ro[v];
}

void hb(int a,int b)
{
	ro[find(a)]=find(b);
}

void reRO()
{
	for(int i=1;i<=n;i++)ro[i]=i;
}

void kru()
{
	sort(ex+1 , ex+1+m);
	int tot=n;
	for(int i=1; i<=m ;i++)
	{
		if(tot==1)break;
		if(find(ex[i].u)!=find(ex[i].v))//两点不在同一集合 
		{
			hb(ex[i].u , ex[i].v);
			add(ex[i].u,ex[i].v,ex[i].w);
			add(ex[i].v,ex[i].u,ex[i].w);
			tot--;
		}
	}
}

void dfs(int u)
{
	vis[u]=1;
	belong[u]=color;
	for(int i=head[u]; i ;i=e[i].nxt )
	{
		int v = e[i].v;
		if(!vis[v])
		{
			depth[v] = depth[u]+1;
			f[v][0] = u;
			w[v][0] = e[i].w;
			for(int j=1; j<=lg[depth[v]] ;j++)
				f[v][j] = f[f[v][j-1]][j-1];
			dfs(v);
		 } 
	}
}

void reLCA()
{
	for(int i=1; i<=n ;i++)
		lg[i] = lg[i-1] + (1 << lg[i-1] == i);
	memset(w,inf,sizeof(w));
	for(int i=1; i<=n ;i++)
	{
		if(!vis[i])
		{
			++color;
			depth[i]=1;
			dfs(i);
		}
	}
	for(int i=1; i<=n ;i++) 
		for(int j=1; j<=lg[depth[i]] ;j++)
			w[i][j] = min(w[f[i][j-1]][j-1] , w[i][j-1]);
}

int lca(int a,int b)
{
	int ans=inf;
	if(depth[a]<depth[b])swap(a,b);
	while(depth[a]>depth[b])
	{
		ans = min(ans , w[a][lg[depth[a]-depth[b]]-1]);
		a = f[a][lg[depth[a]-depth[b]]-1];
	} 
	if(a==b)return ans;
	for(int i = lg[depth[a]]; i>=0 ;i--)
	{
		if(f[a][i] != f[b][i])
		{
			ans = min(ans , w[a][i]);
			ans = min(ans , w[b][i]);
			a = f[a][i];
			b= f[b][i];
		}
	}
	ans = min(ans , w[a][0]);
	ans = min(ans , w[b][0]);
	return ans;
}


void in()
{
	read(n),read(m);
	reRO();//初始化并查集 
	for(int i=1; i<=m ;i++)
	{
		int a,b,c;
		read(a),read(b),read(c);
		ex[i].u=a;ex[i].v=b;ex[i].w=c;
	}
	kru();//最大生成树
	reLCA();//初始化lca 
}

void question()
{
	read(q);
	for(int i=1; i<=q ;i++)
	{
		int a,b;
		read(a),read(b);
		if(belong[a]!=belong[b])
			cout<<-1<<'\n';
		else
			cout<<lca(a,b)<<'\n';
	} 
}

int main()
{
	in();
	question();
}
2021/7/22 10:37
加载中...