这是一个递归函数,如果f[x] = x,说明这个点已经是该团伙的代表人,直接返回就好了,如果它不是该团伙的代表人,那么就返回自己指向的点的团伙代表人 。
在求getFather(3)时,f[3] != 3,返回getFather(f[3])也就是getFather(1);
在求getFather(1)时,f[1] != 1,返回getFather(f[1])也就是getFather(4);
在求getFather(4)时,f[4] == 4,返回4 。递归结束 。最后计算出3的团伙代表人是4 。
4. 查询顶点是否在同一团伙并查集的最后一种操作叫做查询,就是查询两个点是否连通(在同一团伙) 。
前面已经讲了,当两个点所在团伙“代表人”相同,则这两个点所在团伙相同 。判断两个点a、b在同一团伙的方法就是:
getFather(a) == getFather(b)
5. 完整代码const int N = 100; // 节点数量int f[N];int init() { // 初始化 for (int i=0; i<N; i++) f[i] == i;}int getFather(int x) { // 查询所在团伙代表人 return f[x]==x ? x : getFather(f[x]);}int merge(int a, int b) { // 合并操作 f[getFather(a)] = getFather(b);}bool query(int a, int b) { // 查询操作 return getFather(a) == getFather(b);}int main() { init(); merge(3, 1); // 3和1是亲戚 merge(1, 4); // 1和4是亲戚 cout << getFather(3) << endl; // 输出3的团伙代表人+换行 cout << query(3, 1) << endl; // 输出3和1是否是亲戚+换行}并查集巧妙吧!我们既没有构建图,也没有构建边,自始至终只用到了f数组,又优化了时间 。
不要小瞧并查集代码短,在很多时候并查集都会派上用场,比如著名的克鲁斯卡尔算法,就是通过并查集判断两个顶点是否相连的 。更重要的是体会并查集的思想,用这种思想来优化代码 。
推荐阅读
- Linux下如何知道是否有人在使坏?
- 经期减肥喝什么茶呢,春节减肥喝什么茶
- 暗藏在QQ邮箱、百度网盘的国密算法到底是如何实现的?
- 关羽为什么没有守住荆州 赵云守荆州结局会怎样
- 三国演义庞德大战关羽 庞德和关羽大战是多少回
- 切尔诺贝利是真实事件吗 切尔诺贝利事件变异
- 刘彻是汉武帝吗? 汉武帝刘彻一生命运
- 古代真实的圣旨 古代为什么没有人伪造圣旨
- 徐晃击败关羽之战 徐晃打败关羽了吗
- 春节扫尘的风俗的寓意 春节扫尘的寓意是什么
