并查集
来源:互联网 发布:太平天国失败 知乎 编辑:程序博客网 时间:2024/06/16 03:09
并查集
Description
这是一道模板题。
维护一个 n 点的无向图,支持:
- 加入一条连接 u 和 v 的无向边
- 查询 u 和 v 的连通性
由于本题数据较大,因此输出的时候采用特殊的输出方式:用 0 或 1 代表每个询问的答案,将每个询问的答案一次从左到右排列,把得到的串视为一个二进制数,输出这个二进制数 mod 998244353 的值。
Input
第一行包含两个整数 n,m,表示点的个数和操作的数目。n≤4000000,m≤8000000接下来 m 行每行包括三个整数 op,u,v。
如果 op=0,则表示加入一条连接 u 和 v 的无向边;如果 op=1,则表示查询 u 和 v 的连通性。
Output
一行包括一个整数表示答案。
Sample Input 1
3 61 1 00 0 11 0 11 1 20 2 11 2 1
//sum计算时就要mod......
#include <iostream>#include <stdio.h>#include <cstring>#include <cmath>using namespace std;const long long Mod=998244353;int n,m;int op,u,v;int f[4000004];int Find(int a){ if(f[a]==a)return a; return f[a]=Find(f[a]);}void unit(int a,int b){ if(a>b) { int t=a; a=b; b=t; } int x=Find(a); int y=Find(b); if(x!=y)f[y]=x;}int main(){ scanf("%d%d",&n,&m); long long sum=0; for(int i=0;i<n;i++) f[i]=i; for(int i=0;i<m;i++) { scanf("%d%d%d",&op,&u,&v); if(op==0) { unit(u,v); // cout<<f[u]<<" "<<f[v]<<endl; } if(op==1) { if(Find(u)==Find(v)) { sum=sum<<1; sum++; sum=sum%Mod; //边sum边mod!!!!! // cout<<sum<<endl; } else { sum=sum<<1; sum=sum%Mod; // cout<<sum<<endl; } } } cout<<sum%Mod<<endl; /* if(sum>Mod) { sum-=Mod; cout<<sum<<endl; } else cout<<sum<<endl; */return 0;}
阅读全文