反集
如果a
和b
是敌人,合并n+b
和a
,n+a
和b
如果c
和a
是敌人,合并n+c
和a
,n+a
和c
那么b
和c
自然就合并在一起了
这样就符合了题目敌人的敌人是朋友的规则
注意
并查集不要忘了初始化
注意
输入的时候scanf
要用%s
因为scanf
遇见空格是不会跳的,所以尽量这种时候就不要用scanf
,比较麻烦,cin
它不香嘛
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e5+7;
const ll mod=2147483647;
ll n,m;
ll f[N];
inline void init()//并查集必须要初始化!
{
for(int i=1;i<=(n<<1|1);++i)
f[i]=i;
}
inline ll finds(ll x)
{
return f[x]==x?x:f[x]=finds(f[x]);
}
inline void add(ll x,ll y)
{
x=finds(x);
y=finds(y);
f[x]=y;
}
inline bool check(ll x,ll y)
{
x=finds(x);
y=finds(y);
return x==y;
}
int main()
{
scanf("%lld %lld",&n,&m);
init();
for(int i=1;i<=m;++i)
{
ll a,b;
char ch[2];
scanf("%s%lld%lld",&ch,&a,&b);//注意这一点要用%s 因为scanf遇见空格是不会跳的,所以尽量这种时候就不要用scanf,比较麻烦,cin它不香嘛
//cin>>ch>>a>>b;
if(ch[0]=='F')add(a,b);
else {
add(a+n,b);//反集
add(b+n,a);//敌人的敌人就是我的朋友
}
}
ll ans=0;
for(int i=1;i<=n;++i)//查祖先数
if(f[i]==i)ans++;
printf("%lld\n",ans);
return 0;
}
有任何疑问欢迎评论哦虽然我真的很菜
点个关注再走吧