洛谷 P1892 团伙
#include<cstdio> int fa[2500];//fa[i]表示i的朋友所在集合,fa[i+n]表示i的敌人所在集合 bool boo[2500]; int ans,n,m; int find(int x) { if(fa[x]!=x) fa[x]=find(fa[x]); return fa[x]; } void union1(int x,int y) { int fx=find(x); int fy=find(y); fa[fx]=fy; }//标准的并查集的写法 int main() { int i,p,q,k; char c; scanf("%d%d",&n,&m); for(i=1;i<=2*n;i++) fa[i]=i;//初始化,最大要初始化的是fa[n+n]即fa[2*n] for(i=1;i<=m;i++) { scanf("\n%c%d%d",&c,&p,&q); if(c=='F') { union1(p,q); //union1(p+n,q+n);//别搞错了,没有说朋友的敌人一定是敌人,也没有说自己的敌人与朋友的敌人一定是朋友 } if(c=='E') { union1(p,q+n);//合并p的朋友与q的敌人(q的敌人就是p的敌人的敌人) union1(p+n,q);//与上面一行类似 } } for(i=1;i<=n;i++)//判断1-n中有几个集合,每个集合一个团队时团队数量最多(合并集合只可以减少团队,而要满足题意最少也要这么多集合) { k=find(i); if(boo[k]==false) { boo[k]=true; ans++; } } printf("%d",ans); return 0; }