社区讨论

按秩合并并查集求助

学术版参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lujqjqnh
此快照首次捕获于
2024/04/03 19:39
2 年前
此快照最后确认于
2024/04/03 22:30
2 年前
查看原帖
题意大概是:有 nn 个点,mm 个操作, 0 i j 表示 i 与 j 之间连了一条边,1 i j 表示查询 i j 两点最早在连第几条边时连通,如果当前没有连通输出 0。同时要求强制在线。代码是按秩合并并查集,但是 TLE 了,不知道咋整。
CPP
#include<bits/stdc++.h>
int read()
{
	char ch=getchar();
	int x=0;
	while(ch<'0'||ch>'9')
		ch=getchar();
	while(ch>='0'&&ch<='9')
		x=(x<<3)+(x<<1)+(ch&15),ch=getchar();
	return x;
}
template <class type>
type max(type a,type b){return a>b?a:b;}
const int N=5e5+5;
int n,m,f[N],dep[N],depth[N],dis[N],lasans,rid;
int find(int x)
{
	if(f[x]==x)
		return x;
	int F=find(f[x]);
	dep[x]=dep[f[x]]+1;
	return F;
}
void merge(int u,int v,int w)
{
	int fu=find(u),fv=find(v);
	if(fu==fv)
		return;
	if(depth[u]<depth[v])
	{
		std::swap(fu,fv);
		std::swap(u,v);
	}
	f[fv]=fu;
	depth[fu]=max(depth[fu],depth[fv]+1);
	dis[fv]=w;
}
int query(int u,int v)
{
	int fu=find(u),fv=find(v);
	if(fu!=fv)
		return 0;
	int res=0;
	while(u!=v)
	{
		if(dep[u]>dep[v])
			res=max(res,dis[u]),u=f[u];
		else
			res=max(res,dis[v]),v=f[v];
	}
	return res;
}
int main()
{
	n=read(),m=read();
	for(int i=1;i<=n;++i)
		f[i]=i,dep[i]=1,depth[i]=1;
	for(int i=1,opt,u,v;i<=m;++i)
	{
		opt=read(),u=read(),v=read();
		u^=lasans;
		v^=lasans;
		if(!opt)
		{
			++rid;
			merge(u,v,rid);
		}
		else
		{
			lasans=query(u,v);
			printf("%d\n",lasans);
		}
	}
}

回复

2 条回复,欢迎继续交流。

正在加载回复...