……

解题报告: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;
}
``
posted @ 2020-04-19 13:41  童话镇里的星河  阅读(125)  评论(0编辑  收藏  举报