用并查集判断图的连通性

最近写代码遇到一个问题。如图一个3*3*3的Cube在这里插入图片描述

当两个立方体之间共享一个面,称为面邻居(R-6);当两个立方体仅共享一条边,称为边邻居(R-18);仅共享一个点,称为点邻居(R-26)。在细化骨架的算法中,判断一个体素是否为简单体素的时候要判断,删除体素前后欧拉示性数、连通分量数是否发生改变。这个连通分量数,把立方体当成图中的点,两个立方体之间点相邻代表他们之间有边,可以转换成图深搜、广搜去判断没有中心体素前后的连通分量数。在体网格模型里,从点邻接关系独立抽出中心体素的R-26有点麻烦,所以改变角度,从八分圆的邻接关系去判断。八分圆就是中心体素八个顶点为中心的2*2*2的Cube,当两个八分圆之间有重叠部分代表两个八分圆相邻。
因此问题还是回到图的连通判断。判断图的连通性可以深搜、广搜、并查集。
下面这道题目的场景非常相似。

班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。
给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。如果M[i][j] = 1,表示已知第 i 个和 j 个学生互为朋友关系,否则为不知道。你必须输出所有学生中的已知的朋友圈总数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/friend-circles
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

第一版可以AC的代码。结果:52ms,14.1mb。

//Union_Find
class solver {
   
public:
	solver(int n) {
   
		count = n;
		root.resize(n);
		for (int i = 0; i < n; i++)
			root[i] = i;
	}
	//connect x and y
	void connect(int x, int y) {
   
		int xroot = find(x);
		int yroot = find(y);
		if (xroot == yroot) {
   
			return;
		}
		root[yroot] = xroot;
		count--;
	}
	//judge two point is neighbor
	bool isConnected(int x, int y) {
   
		int xroot = find(x);
		int yroot = find(y);
		return xroot == yroot;
	}
	//return count
	int count_num() {
   
		return count;
	}
private:
	int count;
	vector<int> root;
	//get root of x
	int find(int x) {
   
		while (root[x] != x)
			x = root[x];
		return x;
	}
};

//LeetCode内置的判题系统太复杂,上面写了一个求解器来包含并查集的函数,简单易懂
class Solution {
   
public:
	int findCircleNum(vector<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值