Geeks Union-Find Algorithm Union By Rank and Path Compression 图环算法
相同是查找一个图是否有环的算法,可是这个算法非常牛逼,构造树的时候能够达到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" );
}
};
Geeks Union-Find Algorithm Union By Rank and Path Compression 图环算法的更多相关文章
- 转 SQL Union和SQL Union All两者用法区别效率以及与order by 和 group by配合问题
SQL Union和SQL Union All两者用法区别效率以及与order by 和 group by配合问题 SQL Union和SQL Union All用法 SQL UNION 操作符 UN ...
- 关于UNION ALL与 UNION 用法和区别
(转自:http://www.cnblogs.com/EricaMIN1987_IT/archive/2011/01/20/1940188.html) UNION指令的目的是将两个SQL语句的结果合并 ...
- SQL Union和SQL Union All用法
SQL UNION 操作符 UNION 操作符用于合并两个或多个 SELECT 语句的结果集. 请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列.列也必须拥有相似的数据类型.同时,每 ...
- union 和 all union
sql union用法和sql union all用法,sql union效率 1.sql union用法 sql union在查询中可以将两个SQL 语句的结果合并起来.如果这样看的话, UNION ...
- 从Random Walk谈到Bacterial foraging optimization algorithm(BFOA),再谈到Ramdom Walk Graph Segmentation图分割算法
1. 从细菌的趋化性谈起 0x1:物质化学浓度梯度 类似于概率分布中概率密度的概念.在溶液中存在不同的浓度区域. 如放一颗糖在水盆里,糖慢慢溶于水,糖附近的水含糖量比远离糖的水含糖量要高,也就是糖附近 ...
- UNion ALL 和 UNION 的区别
UNION: 指定合并多个结果集并将其作为单个结果集返回.ALL: 将全部行并入结果中.其中包括重复行.如果未指定该参数,则删除重复行.
- linq 多个left join 和 sql union all -> linq union 方法
( from s in Base_SysMenus join r in Base_RoleRights on s.Menu_Id equals r.Menu_Id into temp f ...
- UNION ALL vs UNION
一直没意识到它们之间的区别,只知道UNION ALL在性能上优于UNION,忽略一个很重要的区别:UNION会去掉重复的行,而UNION ALL是包括所有行.
- [Union]C++中Union学习笔记
C++ union结构式一种特殊的类.它能够包含访问权限.成员变量.成员函数(可以包含构造函数和析构函数).它不能包含虚函数和静态数据变量.它也不能被用作其他类的基类,它本身也不能有从某个基类派生而来 ...
随机推荐
- 80x86 CPU 的工作模式
8086/8088微处理器只有一种工作模式:实地址模式. 32为的80x86微处理器有3种工作模式:实地址模式.保护模式和虚拟8086模式. 实地址模式 对于8086/8088微处理器,实模式是它 ...
- visio 画类图时 方法里如何加参数
鼠标双击类(打开属性对话框)-->(类别)操作-->属性-->(类别)参数-->(添加参数)
- QT vs x64编译
下载qt-everywhere-opensource-src-5.3.0 这个设置非常重要,不对的话,一大堆编译错误,已经折腾了好多回了 configure -mp -confirm-license ...
- coursera课程Text Retrieval and Search Engines之Week 3 Overview
Week 3 OverviewHelp Center Week 3 On this page: Instructional Activities Time Goals and Objectives K ...
- 【BZOJ】【3771】Triple
生成函数+FFT Orz PoPoQQQ 这个题要算组合的方案,而且范围特别大……所以我们可以利用生成函数来算 生成函数是一个形式幂级数,普通生成函数可以拿来算多重集组合……好吧我承认以上是在瞎扯→_ ...
- unity opaque sort
https://docs.unity3d.com/ScriptReference/Rendering.OpaqueSortMode.html unity对opaque的排序 tbdr下不排序 其它由近 ...
- HTTP响应状态码【总结】
常见的状态码 [1XX]表示[消息] [2XX]表示[成功] [3XX]表示[重定向] [4XX]表示[请求错误] [5XX]表示[服务器端错误] 200:OK.请求被正常处理 204:No Cont ...
- JS中应用正则表达式转换大小写
JS中应用正则表达式转换大小写,代码很简单,看代码: 以下首字母大写,其它字母小写 <script type="text/javascript"> function r ...
- rcp(插件开发) The 'Eclipse-LazyStart' header is deprecated, use 'Bundle-ActivationPolicy'
'Eclipse-LazyStart' 这个规范在3.4 osgi 4.1 以后就不支持了 大家使用Bundle-ActivationPolicy: lazy 这个属性来实现插件的懒加载吧!
- Linux上如何查看Deb和RPM软件包的更新日志
导读 当一个程序或库打包成Deb或RPM软件包后会有一些元数据文件包含在其中,其中之一就是 changelog文件,它记录了软件包每次更新后发生了什么变化.因此,如果你想找出你安装或更新的软件包发生了 ...