并查集---无向图详细题解

题目描述

这是一道模板题。
维护一个 nn 点的无向图,支持: 加入一条连接 uu 和 vv 的无向边
查询 uu 和 vv 的连通性
由于本题数据较大,因此输出的时候采用特殊的输出方式:用
00 或 11 代表每个询问的答案,将每个询问的答案依次从左到右排列,把得到的串视为一个二进制数,输出这个二进制数 mod 998244353 的值。
请务必使用快读。

输入

第一行包含两个整数n,m,表示点的个数和操作的数目。
接下来m行每行包括三个整数op,u,V。
·如果op=0,则表示加入一条连接u和v的无向边;
·如果op=1,则表示查询u和v的连通性。

输出

一行包括一个整数表示答案。

样例输入

3 6
1 1 0
0 0 1
1 0 1
1 1 2
0 2 1
1 2 1

样例输出

5

题解

这是一个并查集的题,题目本来不难,不过有一些需要注意的地方
1、mod 998244353,表示对mod取余,即对998244353取余

2、求sum的时候需要边求边取余

3、并的时候,应该统一以小的数字为根节点

下面是AC代码

#include<iostream>
using namespace std;

int father[4000004];
long long ans=0;
int k=1;
int temp;
const long long mod=998244353;
//int find(int k)
{
	if(father[k]!=k) 
		father[k]=find(father[k]);
	return father[k];
}
//并
void unionn(int x,int y)
{
	if(x>y) temp=x,x=y,y=temp;
	x=find(x);
	y=find(y);
	if(x!=y)
		father[y]=x;
} 

int main()
{
	int m,n,i,a,b,s1,s2,op;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++)
		father[i]=i;
	for(i=1;i<=m;i++)
	{
		scanf("%d %d %d",&op,&a,&b);
		if(op==0)
		{
			unionn(a,b);
		}
		else
		{
			if(find(a)==find(b))
			{
				ans*=2;
				ans++;
				ans%=mod;
			}
			else
			{
				ans*=2;
				ans%=mod;
			}
					
		}
	}	
	cout<<ans<<endl;
	return 0;
}

对于并查集还不是很清楚的,可以去看我的前一篇文章,通过3个例子带你来了解并查集链接在此
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_45721778/article/details/105539508