P1892 [BOI2003]团伙
分析
从题目我们容易分析,这题是用并查集扩展域去写的。
可以通过两个限制条件,来得到两个式子
- 朋友的朋友是我的朋友 <=> p[a]=b
- 与我敌对的人有敌对关系的人,是我的朋友 <=> p[a+n]=b,p[b+n]=a;
易错点:这点给我卡成SB了,就是我一直认为p[a+n]=p[b+n]的,就是说,朋友的敌人也是我的敌人,其实是不一定的,朋友的敌人,不一定是我的敌人。这是和奇偶游戏很不相同的一大点,在奇偶游戏中,奇偶不相同,那就说明你跟我相反的一定是相同的。而奇偶相同,则说明相反的一定是相同的。
这里要着重说一下反集的概念,反集代表的是与当前集合性质相反的集合,只要把握住这一点去进行集合合并就不会出现奇怪的错误了。
AC_Code
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int p[N*2];
bool st[N*2];
int n,m,res;
int find(int x)
{
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
int main()
{
cin>>n>>m;
for(int i=1;i<=2*n;i++) p[i]=i;
while(m--)
{
int a,b;
char op;
cin>>op>>a>>b;
int pa = find(a+n),pb = find(b+n);
a = find(a), b = find(b);
if(op=='E') p[pa]=b,p[pb]=a;
else p[a]=b;
}
for(int i=1;i<=n;i++){
int x = find(i);
if(!st[x]){
//cout<<x<<endl;
st[x]=1;
res++;
}
}
cout<<res<<endl;
return 0;
}

浙公网安备 33010602011771号