基础代码模板
(1)朴素并查集: int p[N]; //存储每个点的父节点 // 返回x的父节点 int find(int x) { if (p[x] != x) p[x] = find(p[x]); return p[x]; } // 初始化,假定节点编号是1~n for (int i = 1; i <= n; i ++ ) p[i] = i; // 合并a和b所在的两个集合: void Union(int a,int b){ p[find(a)] = find(b); }
(2)维护size的并查集: int p[N], size[N]; //p[]存储每个点的父节点, size[]只有父节点的有意义,表示父节点所在集合中的点的数量 // 返回x的父节点 int find(int x) { if (p[x] != x) p[x] = find(p[x]); return p[x]; } // 初始化,假定节点编号是1~n for (int i = 1; i <= n; i ++ ) { p[i] = i; size[i] = 1; } // 合并a和b所在的两个集合: void Union(int a,int b){ size[find(b)] += size[find(a)]; p[find(a)] = find(b); }
例题讲解:省份数量
题目描述:
有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。 省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。 给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。 返回矩阵中 省份 的数量。
示例 1:
输入:isConnected = [[1,1,0],[1,1,0],[0,0,1]] 输出:2示例 2:
输入:isConnected = [[1,0,0],[0,1,0],[0,0,1]] 输出:3提示:
- 1 <= n <= 200
- n == isConnected.length
- n == isConnected[i].length
- isConnected[i][j] 为 1 或 0
- isConnected[i][i] == 1
- isConnected[i][j] == isConnected[j][i]
题解:图的顶点数为 n,则初始化 n 个单顶点集合,每个集合指向自身。然后遍历图中的每个顶点,将当前顶点与其邻接点进行合并。最终结果返回合并后的集合的数量即可。