首页 技术 正文
技术 2022年11月9日
0 收藏 692 点赞 4,548 浏览 1896 个字

相同是查找一个图是否有环的算法,可是这个算法非常牛逼,构造树的时候能够达到O(lgn)时间效率。n代表顶点数

原因是依据须要缩减了树的高度,也叫压缩路径(Path compression),名字非常高深,只是事实上不难理解,简单来说就是每次查找一个节点的时候,都把这一路径中的全部节点都赋予根节点作为路径。

原文没指出的地方:

也由于须要压缩,所以初始化的时候注意,不能如前面简单有用Union Find的算法那样初始化全部顶点的父母节点为-1,应该是初始化全部节点的父母节点为本身(自己生殖自己?),然后就方便递归的时候一律能够返回这个跟节点了。

当然事实上初始化为-1也是能够的,只是须要额外代码处理一下,也不难。

最后能够參考原文:http://www.geeksforgeeks.org/union-find-algorithm-set-2-union-by-rank/

#pragma once
#include <iostream>class UnionFindUnionByRank
{
struct Edge
{
int src, des;
};struct Graph
{
int V, E;
Edge *edges;
Graph(int v, int e) : V(v), E(e)
{
edges = new Edge[e];
}
~Graph()
{
if (edges) delete [] edges;
}
};struct subSet
{
int parent, rank;
};int find(subSet *subs, int i)
{
//由于要压缩,所以不能使用-1作为根的标志了
if (subs[i].parent != i)
{
//Union by rank: attach smaller rank tree to high rank tree. It is so simple, but very hard to create it totally by ourself, so it's good to stand on the shoulder of the giant.
subs[i].parent = find(subs, subs[i].parent);
}
return subs[i].parent;//由于假设-1作为根标志,那么这里就要返回i,就达不到压缩的效果了,而是应该返回parent,一层一层递归回上一层。
}void unionTwo(subSet *subs, int x, int y)
{
int xroot = find(subs, x);
int yroot = find(subs, y);if (subs[xroot].rank < subs[yroot].rank)
{
subs[xroot].parent = yroot;
}
else if (subs[xroot].rank > subs[yroot].rank)
{
subs[yroot].parent = xroot;
}
else
{
//only need to increment its rank when ther are equal rank
subs[yroot].parent = xroot;
subs[xroot].rank++;
}
}bool isCycle(Graph *gra)
{
subSet *subs = new subSet[gra->V];
for (int i = 0; i < gra->V; i++)
{
subs[i].parent = i;//parent不能初始化为-1
subs[i].rank = 0;
}for (int e = 0; e < gra->E; e++)
{
int x = find(subs, gra->edges[e].src);
int y = find(subs, gra->edges[e].des);if (x == y) return true;unionTwo(subs, x, y);
}return false;
}
public:
UnionFindUnionByRank()
{
int V = 3, E = 3;
struct Graph* graph = new Graph(V, E);// add edge 0-1
graph->edges[0].src = 0;
graph->edges[0].des = 1;// add edge 1-2
graph->edges[1].src = 1;
graph->edges[1].des = 2;// add edge 0-2
graph->edges[2].src = 0;
graph->edges[2].des = 2;if (isCycle(graph))
printf( "Union By Rank found graph contains cycle \n" );
else
printf( "Union By Rank found graph doesn't contain cycle \n" );
}
};

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,495
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,909
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,741
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,496
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,134
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,298