随笔 - 5  文章 - 0  评论 - 0  阅读 - 153

并查集与反集——P1892团伙

并查集

并查集如其名,合并与查找

  • 查找
int find(int key)
{
	if(fa[key]==key) return key;
	else return fa[key]=find(fa[key]);
}
  • 合并
void unite(int x, int y) {
	int fax = find(x);
	int fay = find(y);
	fa[fax] = fay;
	return ;
}

反集

处理并查集合并问题的敌对/朋友关系的一种集合

如此时有两个人,吉吉和毛毛,那么两人根据题意只有两种关系,朋友或者敌人(不考虑两人是陌生人),那么根据这两种关系

  1. 两人是朋友时
    合并吉吉与毛毛,并且合并吉吉的敌人和毛毛的敌人
  2. 两人是敌人时
    合并吉吉与毛毛的敌人,合并毛毛与吉吉的敌人

如何实现这一问题?

定义一个数组 fa[2n],1n 表示朋友关系,n+12n 表示敌人关系

unite(),unite()

unite()unite()

到此为止做这道题目的前置知识已经具备,分析题目的意思,我们并不能知道敌人的朋友就是敌人,或者朋友的敌人就是敌人,所以不需要合并朋友的敌人,即为此步骤unite()不用进行。

code

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005;
int fa[maxn*2];
int n,m;
int find(int key)
{
	if(fa[key]==key) return key;
	else return fa[key]=find(fa[key]);
}
void unite(int x, int y) {
	int fax = find(x);
	int fay = find(y);
	fa[fax] = fay;
	return ;
}
int main() {
	cin>>n>>m;
	for (int i=1;i<=2*n;i++) fa[i]=i;
	for (int i=1;i<=m;i++){
		char op;
		int p,q;
		cin>>op>>p>>q;
		if(op=='F') unite(p,q);
		else if(op=='E') {
			unite(p+n,q);
			unite(q+n,p);
		}
	}
	int ans=0;
	for (int i=1;i<=n;i++)
		if(find(i)==i)
			ans++;
	printf("%d\n", ans);
	return 0;
}

P2024这道题目和这个有相似之处,感兴趣的同学可以尝试一下

posted on   如果有缘我们会再见  阅读(108)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示