题目描述
这是一道模板题。
维护一个 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个例子带你来了解并查集链接在此