C++洛谷B3618 寻找团伙
时间: 2025-02-22 22:29:34 浏览: 45
### C++ 洛谷 B3618 寻找团伙 题解 思路
#### 问题描述
在一个小镇上,有若干个人可能属于不同的团伙。已知一些人之间的关系(朋友或敌人),现在要找出有多少个独立的团伙。
#### 解决方案概述
为了找到所有的团伙,可以采用并查集(Union-Find Set)的数据结构来处理这个问题。通过遍历每一对给出的关系,并根据这些关系更新各个节点所属集合的信息,最终统计不同连通分量的数量即可得到答案。
#### 并查集简介
并查集是一种树型数据结构,用于处理不相交集合的合并与查询操作。其主要功能包括查找某个元素所在的集合以及将两个集合合并成一个新的集合。对于本题而言,当两个人是朋友时就执行一次`union`操作;而如果是敌人则不需要任何动作因为这不会影响到当前所处的团伙划分[^1]。
#### 实现细节
下面是一个完整的程序实现:
```cpp
#include <iostream>
using namespace std;
const int MAX_N = 1e3 + 5;
int parent[MAX_N];
// 初始化函数
void init(int n){
for (int i = 0; i <= n ; ++i) {
parent[i] = i;
}
}
// 查找根结点的同时做路径压缩优化
int findRoot(int x){
if(x != parent[x]){
parent[x] = findRoot(parent[x]);
}
return parent[x];
}
// 合并两个集合
bool unionSet(int a,int b){
int rootA=findRoot(a);
int rootB=findRoot(b);
if(rootA==rootB)return false;
parent[rootA]=rootB;
return true;
}
int main(){
int n,m,a,b;
cin>>n>>m;
init(n); //初始化parent数组
while(m--){
cin >> a >> b;
unionSet(a,b); // 如果a和b是朋友,则把他们放在同一个集合里
}
int count=0;
for(int i=1;i<=n;++i){
if(findRoot(i)==i){ // 统计有多少个代表元(即多少个团伙)
++count;
}
}
cout<<count<<"\n";
}
```
此代码片段实现了上述提到的方法论,在输入部分读入人数`n`及其相互间存在的友好关联数目`m`之后,依次对每一组好友实施联合(`union`)过程直至完成全部关系解析工作。最后再利用循环计算出总共有几个独特的父级成员作为结果输出。
阅读全文
相关推荐













