并查集板子
const int N=10010;
int n,m;
int fa[N];
int find(int k){
if(fa[k]==k) return k;
else return fa[k]=find(fa[k]);
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++){
int x,y,z;
cin>>z>>x>>y;
if(z==1) fa[find(x)]=find(y);
else {
if(fa[find(x)]==find(y))
cout<<"Y"<<endl;
else
cout<<"N"<<endl;
}
}
}
扩展域并查集 + 离散化
P5937 [CEOI1999]Parity Game
#include<iostream>
#include<cstdio>
#include<unordered_map>
using namespace std;
const int N=1e5+10;
int n,m,idx;
int p[N*2+10];
unordered_map<int,int>s;
int read(){
int x=0,f=1; char ch=getchar();
if(ch=='-') f=-1, ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
return x*f;
}
int get(int x){
if(s.count(x)==0) s[x]=++idx;
return s[x];
}
int find(int x){
if(x==p[x]) return x;
else return p[x]=find(p[x]);
}
int main(){
n=read(); m=read(); int res=m;
for(int i=1;i<=N*2;i++) p[i]=i;
for(int i=1;i<=m;i++){
int x=read(), y=read(), t;
string op; cin>>op;
if(op=="even") t=0;
else t=1;
x=get(x-1); y=get(y);
if(t==0){
if(find(x+N)==find(y)) {
res=i-1; break;
}
else{
p[find(x)]=find(y);
p[find(x+N)]=find(y+N);
}
}
else{
if(find(x)==find(y)){
res=i-1; break;
}
else {
p[find(x+N)]=find(y);
p[find(x)]=find(y+N);
}
}
}
printf("%d",res);
}
带边权并查集/压缩路径
P5937 [CEOI1999]Parity Game
#include<iostream>
#include<cstdio>
#include<map>
using namespace std;
const int N=2e5+10;
int n,m,res;
int idx;
int p[N];
int d[N];
map<int,int>s;
int read(){
int x=0,f=1; char ch=getchar();
if(ch=='-') f=-1, ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
return x*f;
}
int get(int x){
if(s.count(x)==0) s[x]=++idx;
return s[x];
}
int find(int x){
if(p[x]!=x){
int root=find(p[x]);
d[x]^=d[p[x]];
p[x]=root;
}
return p[x];
}
int main(){
n=read();
m=read();
res=m;
for(int i=1;i<=N;i++) p[i]=i;
for(int i=1;i<=m;i++){
int x=read(), y=read();
string op; cin>>op;
int a=get(x-1), b=get(y);
int pa=find(a), pb=find(b);
if(op=="even"){
int t=0;
if(pa==pb){
if((d[a]^d[b])!=t){
res=i-1; break;
}
}
else {
p[pa]=pb;
d[pa]=d[a]^d[b]^t;
}
}
else{
int t=1;
if(pa==pb){
if((d[a]^d[b])!=t){
res=i-1; break;
}
}
else{
p[pa]=pb;
d[pa]=d[a]^d[b]^t;
}
}
}
printf("%d",res);
}