// 对应leetcode题目:剑指 Offer II 118. 多余的边
并查集的作用:检查无向图中是否存在环
实现方式:用树来表示集合,并以数组的方式建树,通过查找一个边的两个顶点的根节点的关系判断是否存在环,
若不同,则说明这两个集合是可以通过当前当前的边建立起联系的,即他们属于同一个集合,这时将两棵树合并(暂时简单的将一个根节点挂在另一个根节点下面);
若相同:则说明这两个点在同一个集合内,说明存在了环!
C++的naive实现:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Solution{
public:
vector<int> ans;
int get_parent(vector<int>& parent, int pos) { // 若节点无父节点,返回-1
int ret = pos;
while(parent[ret] != -1) {
ret = parent[ret];
}
return ret;
}
bool insert(vector<int>& parent, int a, int b) {
int p_a = get_parent(parent, a);
int p_b = get_parent(parent, b);
if(p_a == p_b) {
this->ans = {a, b};
return false;
}
else // union
parent[p_a] = p_b; // a接在b下面
return true;
}
vector<int> check_circle(vector<vector<int>>& edges)
{
int n = edges.size();
vector<int> parent(n, -1);
for(int i=0; i<n; i++) {
insert(parent, edges[i][0], edges[i][1]);
}
return ans;
}
};
int main()
{
// 通过 删掉一个边形树(无环图)。若有多种删除方法, 则按照在edges中出现的顺序,返回最后出现的
vector<vector<int>> edges = {{0, 1}, {1, 2}, {3, 4}, {2, 4}, {1, 3}, {2, 5}};
Solution base;
vector<int> ans = base.check_circle(edges);
return 0;
}