算法题 朋友 (并查集)

该博客介绍了如何使用并查集数据结构解决社交网络中的朋友关系查询问题。当A和B是朋友,B和C是朋友时,根据规则A和C也视为朋友。博客提供了输入和输出格式,并给出了样例输入和输出,帮助读者理解如何编写程序来判断两个人在给定的关系网中是否互为朋友。

在社交的过程中,通过朋友,也能认识新的朋友。在某个朋友关系图中,假定 A 和 B 是朋友,B 和 C 是朋友,那么 A 和 C 也会成为朋友。即,我们规定朋友的朋友也是朋友。

现在,已知若干对朋友关系,询问某两个人是不是朋友。

请编写一个程序来解决这个问题吧。

输入格式

第一行:三个整数 n,m,p (n\leq 5000,m\leq 5000,p\leq 5000)n,m,p(n5000,m5000,p5000),分别表示有 nn 个人,

### 关于并查集算法的练习题 #### 题目推荐 以下是几道经典的与并查集算法相关的题目,这些题目可以帮助深入理解掌握该数据结构的应用: 1. **连通分量问题** - 描述:给定一张无向图,判断其中有多少个连通分量。 - 思路:通过初始化每个顶点为独立集合,利用边的信息逐步合并集合,最终统计剩余的根节点数量即可得到连通分量数目[^1]。 2. **朋友圈问题** - 描述:在一个班级里有若干学生,已知某些学生之间存在友谊关系,请计算共有多少个互不重叠的朋友圈。 - 实现方法:可以将每位同学视为单独的一个集合成员;当得知两人成为好友时,则调用 `join` 函数将其所属集合合并。最后遍历所有学生的父亲指针,不同值代表不同的圈子[^3]。 3. **敌友关系判定** - 描述:假设每个人都有可能与其他任何人形成友好或者对立的关系,并且遵循“我的敌人就是你的敌人”的原则扩展这种关联性。现在给出一系列这样的声明,询问任意两个人是否属于同一个阵营。 - 解决方案:采用带标记版本的并查集,在常规基础上增加额外逻辑区分正负两类联系[^3]。 4. **最小生成树中的Kruskal算法实现部分** - 虽然严格意义上不属于纯并查集范畴,但是作为其重要应用场景之一值得提及。此过程涉及按照权重排序后的候选边逐一尝试加入当前森林而不造成环路的操作,而这恰好可以通过维护动态变化着的子树间连接状态来高效完成检测任务[^4]。 ```cpp // C++ Example Code Snippet for Union-Find Implementation #include <vector> using namespace std; class DisjointSet { private: vector<int> parent; public: explicit DisjointSet(int size) : parent(size, -1) {} int find_set(int x){ if(parent[x]<0)return x; return parent[x]=find_set(parent[x]); } bool union_set(int x,int y){ int fx=find_set(x),fy=find_set(y); if(fx==fy)return false; if(-parent[fx]>-parent[fy]){ parent[fx]+=parent[fy]; parent[fy]=fx; } else{ parent[fy]+=parent[fx]; parent[fx]=fy; } return true; } }; ``` #### 结论 以上列举了几类典型的基于并查集解决的实际编程挑战案例。它们覆盖了从基础理论验证到复杂实际场景模拟等多个层面的要求,非常适合用来巩固学习成果以及提升实战能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值