【LOJ 109 并查集】 并查集

题目描述

这是一道模板题。
维护一个 n 点的无向图,支持:

  • 加入一条连接 u 和 v 的无向边
  • 查询 u 和 v 的连通性
    由于本题数据较大,因此输出的时候采用特殊的输出方式:用 0 或 1 代表每个询问的答案,将每个询问的答案依次从左到右排列,把得到的串视为一个二进制数,输出这个二进制数 mod 998244353 的值。

分析

简单的并查集。

AC代码

#include <bits/stdc++.h>
using namespace std;
const int maxn=8000005;
const int Mod=998244353;
struct Edge{
	int u,v;
}edge[maxn];
int a[maxn],fa[maxn];
int n,m,nedge,ans;
inline int read() {
	int x=0,w=0;char ch=0;
	while (!isdigit(ch)) {w|=ch=='-';ch=getchar();}
	while (isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return w?-x:x;
}
void addedge(int a,int b) {
	edge[nedge]=(Edge){a,b};
}
inline int gf(int x) {
	return fa[x]==x?fa[x]:fa[x]=gf(fa[x]);
}
int main() {
	n=read(),m=read();
	for (int i=1;i<=n;i++) fa[i]=i;
	nedge=0; int cnt=0;
	while (m--) {
		int opt=read(),u=read(),v=read();
		if (opt==0) {
			addedge(u,v); addedge(v,u);
			int ance1=gf(u),ance2=gf(v);
			if (ance1!=ance2) fa[ance1]=ance2;
		} 
		else {
			int ance1=gf(u),ance2=gf(v);
			if (ance1==ance2) a[++cnt]=1;
			else a[++cnt]=0;
		}
	}
	int x=1;
	while (a[x]==0) x++;
	for (int i=cnt;i>=x;i--) ans=(ans*2+a[i])%Mod;
	printf("%d
",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/Dawn-Star/p/9803495.html