朴素并查集
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
int n,m;
vector <int> dr[1001];
int py[1001];
int findpy(int x)
{
if(py[x]==x) return x;
return py[x]=findpy(py[x]);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
py[i]=i;
for(int i=1;i<=m;i++)
{
int x,y;char p;
cin>>p;
scanf("%d%d",&x,&y);
if(p=='F')
if(findpy(x)!=findpy(y))
py[findpy(y)]=findpy(x);
else{
dr[y].push_back(x);
dr[x].push_back(y);// 双向
}
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<dr[i].size();j++)
py[findpy(dr[i][j])]=findpy(dr[i][0]);
}
int ans=0;
for(int i=1;i<=n;i++)
if(findpy(i)==i) ans++;
printf("%d",ans);
return 0;
}
反集
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
int f[3000];
int find(int u)
{
//if(f[x]==x) return x;
//return f[x]=find(f[x]);
while(f[u]!=u)
{
u=f[u];
}
return f[u];
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=2*n;i++) f[i]=i;
for(int i=1;i<=m;i++)
{
int x,y;char p;
cin>>p;
scanf("%d%d",&x,&y);
if(p=='F')
if(find(x)!=find(y))
f[find(x)]=find(y);
if(p=='E'){//else 不可以,匹配到最近的if
if(find(x)!=find(y+n))
f[find(y+n)]=find(x);
if(find(x+n)!=find(y))
f[find(x+n)]=find(y);
}
}
int ans=0;
for(int i=1;i<=n;i++)
//printf("%d ",f[i]);
if(f[i]==i) ans++;
printf("%d",ans);
return 0;
}