解题报告:luogu P1892
题目链接:P1892 [BOI2003]团伙
最近懒死了。
和P1525 关押罪犯和相似,也要有一个记录敌人信息的数组。
这里对这个数组有个好些的理解:记录敌人集合中的任意一个,由于并查集的性质,其他的也随之确定。
注意的是,在两个团伙合并时,先前两个团伙已确定的敌人不会因此成为朋友。
\(Code\):
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define read(x) scanf("%d",&x)
int n,m;
int f[1005],b[1005];
int l,r,ans=0;
char flag;
void init(int n){for(int i=1;i<=n;i++) f[i]=i,b[i]=0;}
int getf(int u){return (f[u]==u)?u:f[u]=getf(f[u]);}
void merge(int u,int v){int t1=getf(u),t2=getf(v);if(t1^t2) f[t2]=t1;}
int main()
{
read(n),read(m);
init(n);
for(int i=1;i<=m;i++)
{
cin>>flag;
read(l),read(r);
if(flag=='F')
{
merge(r,l);
/*if(b[l]&&b[r]) merge(b[l],b[r]);
if(b[l]) b[r]=b[l];
else if(b[r]) b[l]=b[r];*/
//如果联合时两团伙的敌人也成为朋友,就把上面注释的东西加上
}
else
{
if(b[l]!=0) merge(b[l],r);
else b[l]=r;
if(b[r]!=0) merge(b[r],l);
else b[r]=l;
}
}
for(int i=1;i<=n;i++) getf(i);
for(int i=1;i<=n;i++) if(f[i]==i) ans++;
printf("%d\n",ans);
return 0;
}
``