题目大意:给定n个人,朋友的朋友是朋友,敌人的敌人是朋友,朋友之间组成一个团伙,求团伙数
将每个点x拆成两个:x和x+n
如果x和y是朋友,就将x和y合并
如果x和y是敌人,就将x和y+n合并,将y和x+n合并
注意敌人的朋友不一定是敌人,因此如果x和y是朋友,不能将x+n和y+n合并
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 1010 using namespace std; int n,m,ans,a[M]; namespace Union_Find_Set{ int fa[M<<1]; int Find(int x) { if(!fa[x]||fa[x]==x) return fa[x]=x; return fa[x]=Find(fa[x]); } void Union(int x,int y) { x=Find(x);y=Find(y); if(x==y) return ; fa[x]=y; } } int main() { using namespace Union_Find_Set; int i,x,y; char p[10]; cin>>n>>m; for(i=1;i<=m;i++) { scanf("%s%d%d",p,&x,&y); if(p[0]=='F') Union(x,y);//Union(x+n,y+n); else Union(x,y+n),Union(x+n,y); } for(i=1;i<=n;i++) a[i]=Find(i); sort(a+1,a+n+1); for(i=1;i<=n;i++) if(i==1||a[i]!=a[i-1]) ++ans; cout<<ans<<endl; return 0; }
时间: 2024-10-12 04:30:41