首页 > 其他分享 >并查集与反集——P1892团伙

并查集与反集——P1892团伙

时间:2024-01-24 16:26:04浏览次数:29  
标签:反集 int 查集 unite P1892 吉吉 fa key 敌人

并查集

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

  • 查找
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[2*n],1-n\) 表示朋友关系,\(n+1-2n\) 表示敌人关系

\(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这道题目和这个有相似之处,感兴趣的同学可以尝试一下

标签:反集,int,查集,unite,P1892,吉吉,fa,key,敌人
From: https://www.cnblogs.com/marshuo/p/17984941

相关文章

  • 并查集
    并查集是一种集合结构,用来处理集合的合并和查询问题。主要有两个函数:合并和查询合并函数表示合并两个不同的集合查询表示当前元素属于那个集合逻辑结构是单链表的结构,每个节点向上指向一个属于的集合的代表元素,这个集合的代表元素的next指向它自己成环,表示这个集合的代表元素......
  • CF-292-D-并查集
    292-D题目大意给定一张无向图,由\(n\)个顶点\(m\)条边。有\(q\)次询问,每次询问将\([l,r]\)的边删去,问图中有多少连通分量。Solution涉及连通分量,尝试应用并查集解决。记录一个前缀并查集\(pre[i]\),表示前\(i\)条边连通后的图;和一个后缀并查集\(suf[i]\),表示后\(m-i\)条边连通......
  • CF-915-F-并查集
    915-F题目大意给定一棵\(n\)个节点的树,节点带权,设函数\(I(x,y)\)等于点\(x\)到点\(y\)的路径上最大的点权与最小的点权之差。求:\[\sum_{i=1}^{n}\sum_{j=i}^{n}I(i,j)\]Solution令函数\(F(i,j)\)等于点\(x\)到点\(y\)的路径上最大的点权,函数\(G(i,j)\)等于点\(x\)到点\(y\)......
  • 并查集综合
    种类并查集关押罪犯经典种类并查集。考虑要想使最后的结果尽可能小,必须按照怨气值大小将每组关系排序,从大到小依次将罪犯放入监狱。对于放的过程,用并查集维护。由于我们已经将怨气值大小排序,所以对于一组\(a\)与\(b\)的矛盾,将\(a\)与\(b\)不放在同一个监狱一定是最优......
  • 并查集
    并查集基础并查集(\(\sfDisjoint\Set\Union\),\(\sfDSU\))是一种用于管理元素所属集合的数据结构,实现为一个森林,其中每棵树表示一个集合,树中的节点表示对应集合中的元素。初始化:初始化时每个节点均为一个集合,因此根节点初始化为自己。for(inti=1;i<=n;i++)fa[i]......
  • abc097d<并查集,排列>
    题目D-Equals给出\(1\simn\)的排列p,给出\(m\)种对换\((p_i,p_j)\),在这\(m\)种对换中任选操作,对原排列对换任意多次。求能够实现的\(p_i=i\)的最大个数为多少?思路将m中对换中能够相互关联的位置归为一组,这组位置之间可通过对换操作实现任意顺序;因而对于一组内的数据,是......
  • 并查集基础 &打击罪犯
    并查集基础真的很基础题目描述:Description某个地区有n(n<=1000)个犯罪团伙,当地警方按照他们的危险程度由高到低给他们编号为1-n,他们有些团伙之间有直接联系,但是任意两个团伙都可以通过直接或间接的方式联系,这样这里就形成了一个庞大的犯罪集团,犯罪集团的危险程度唯一由集团内的......
  • 并查集
    并查集并查集是一种采用树形结构存储的集合,可以高效的查找两个元素是否在一个集合当中以及合并两个集合。这里的树形结构并非仅指二叉树,而是一个节点可以有多个孩子。对于一个并查集的节点,它可以有两个元素,一个存储该节点的数据,另一个用来指向其父节点。当然当我们所存储的元......
  • (来一套)JavaScript并查集模板
    code: classUnionFind{constructor(n){this.parent=Array.from({length:n},(_,i)=>i);this.size=newArray(n).fill(1);this.cnt=n;}findset(x){if(this.parent[x]===x){returnx......
  • 带权并查集
    对于种类并查集主要是考虑清楚到根节点距离分为几类,每一类的意义有的题目相出d数组的含义才能想到用带权并查集//find函数需要变化intfind(intx){if(p[x]!=x){introot=find(p[x]);d[x]+=d[p[x]];p[x]=root;}retur......