Union-Find 检测无向图有无环路算法
不相交集合数据结构(Disjoint-set data structure)是一种用于跟踪集合被分割成多个不相交的子集合的数据结构,每个集合通过一个代表来标识,代表即集合中的某个成员。
Union-Find 算法为该数据结构提供了两种非常有用的操作:
- Find:判断子集中是否存在特定的元素。可以用于检测是否两个元素存在于相同的子集中。
- Union:将两个不子集合并成新的子集合。
Union-Find 算法的一个具体的应用就是在无向图(Undirected Graph)中检测是否存在环路(Cycle)。
例如,下面这张无向图 G:
0
| \
| \
1-----2
G 中包含 3 个顶点和 3 条边 {{0, 1}, {1, 2}, {2, 1}}。
初始时,设 int[] parent = new int[VertexCount],默认每个顶点的子集中只有自己,设为 -1。
0 1 2
-1 -1 -1
处理边 {0, 1},Find 顶点 0 和 1 的子集,发现它们在不同的子集中,则 Union 它们,此时 1 代表了子集 {0, 1}。
0 1 2
1 -1 -1
处理边 {1, 2},Find 顶点 1 和 2 的子集,发现它们在不同的子集中,则 Union 它们,此时 2 代表了子集 {0, 1, 2}。
0 1 2
1 2 -1
处理边 {2, 1},Find 顶点 2 和 1 的子集,发现它们在相同的子集中,则图存在环。
Union-Find 算法简单实现如下,其时间复杂度为 O(n)。
using System;
using System.Collections.Generic;
using System.Linq; namespace GraphAlgorithmTesting
{
class Program
{
static void Main(string[] args)
{
Graph g = new Graph();
g.AddEdge(, , );
g.AddEdge(, , );
g.AddEdge(, , );
g.AddEdge(, , );
//g.AddEdge(2, 1, 4);
g.AddEdge(, , );
//g.AddEdge(3, 2, 9);
g.AddEdge(, , );
//g.AddEdge(4, 3, 7);
//g.AddEdge(4, 5, 4); Console.WriteLine();
Console.WriteLine("Graph Vertex Count : {0}", g.VertexCount);
Console.WriteLine("Graph Edge Count : {0}", g.EdgeCount);
Console.WriteLine(); Console.WriteLine("Is there cycle in graph: {0}", g.HasCycle()); Console.ReadKey();
} class Edge
{
public Edge(int begin, int end, int weight)
{
this.Begin = begin;
this.End = end;
this.Weight = weight;
} public int Begin { get; private set; }
public int End { get; private set; }
public int Weight { get; private set; } public override string ToString()
{
return string.Format(
"Begin[{0}], End[{1}], Weight[{2}]",
Begin, End, Weight);
}
} class Graph
{
private Dictionary<int, List<Edge>> _adjacentEdges
= new Dictionary<int, List<Edge>>(); public Graph(int vertexCount)
{
this.VertexCount = vertexCount;
} public int VertexCount { get; private set; } public IEnumerable<int> Vertices { get { return _adjacentEdges.Keys; } } public IEnumerable<Edge> Edges
{
get { return _adjacentEdges.Values.SelectMany(e => e); }
} public int EdgeCount { get { return this.Edges.Count(); } } public void AddEdge(int begin, int end, int weight)
{
if (!_adjacentEdges.ContainsKey(begin))
{
var edges = new List<Edge>();
_adjacentEdges.Add(begin, edges);
} _adjacentEdges[begin].Add(new Edge(begin, end, weight));
} private int Find(int[] parent, int i)
{
if (parent[i] == -)
return i;
return Find(parent, parent[i]);
} private void Union(int[] parent, int x, int y)
{
int xset = Find(parent, x);
int yset = Find(parent, y);
parent[xset] = yset;
} public bool HasCycle()
{
int[] parent = new int[VertexCount];
for (int i = ; i < parent.Length; i++)
{
parent[i] = -;
} // Iterate through all edges of graph, find subset of both
// vertices of every edge, if both subsets are same,
// then there is cycle in graph.
foreach (var edge in this.Edges)
{
int x = Find(parent, edge.Begin);
int y = Find(parent, edge.End); if (x == y)
{
return true;
} Union(parent, x, y);
} return false;
}
}
}
}
本篇文章《Union-Find 检测无向图有无环路算法》由 Dennis Gao 发表自博客园,未经作者本人同意禁止任何形式的转载,任何自动或人为的爬虫转载行为均为耍流氓。
Union-Find 检测无向图有无环路算法的更多相关文章
- CVPR目标检测与实例分割算法解析:FCOS(2019),Mask R-CNN(2019),PolarMask(2020)
CVPR目标检测与实例分割算法解析:FCOS(2019),Mask R-CNN(2019),PolarMask(2020)1. 目标检测:FCOS(CVPR 2019)目标检测算法FCOS(FCOS: ...
- [算法]检测空间三角形相交算法(Devillers & Guigue算法)
#pragma once //GYDevillersTriangle.h /* 快速检测空间三角形相交算法的代码实现(Devillers & Guigue算法) 博客原地址:http://bl ...
- UEBA 学术界研究现状——用户行为异常检测思路:序列挖掘prefixspan,HMM,LSTM/CNN,SVM异常检测,聚类CURE算法
论文 技术分析<关于网络分层信息泄漏点快速检测仿真> "1.基于动态阈值的泄露点快速检测方法,采样Mallat算法对网络分层信息的离散采样数据进行离散小波变换;利用滑动窗口对该尺 ...
- 特征点检测学习_2(surf算法)
依旧转载自作者:tornadomeet 出处:http://www.cnblogs.com/tornadomeet 特征点检测学习_2(surf算法) 在上篇博客特征点检测学习_1(sift算法) 中 ...
- 模式匹配之surf----特征点检测学习_2(surf算法)
在上篇博客特征点检测学习_1(sift算法) 中简单介绍了经典的sift算法,sift算法比较稳定,检测到的特征点也比较多,其最大的确定是计算复杂度较高.后面有不少学者对其进行了改进,其中比较出名的就 ...
- 图论 Make Unique:有向图和无向图的一些算法
计算机科学入门资料之一的<算法与数据结构-C语言版>,覆盖了基础算法的几乎所有分支,其中的一个典型分支为图理论. 一个简介:图论基础-图数据结构基础 一个简洁的博客:图论基础,简列一本书 ...
- 当我们谈论算法我们在谈论什么:由疫情核酸检测想到的分治算法(Divide-and-Conquer)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_159 北京的疫情一波未平一波又起,由此看来,战"疫"将是一场旷日持久的战争,绝不能掉以轻心.轻易言胜.病毒随时 ...
- 无向图的最短路径算法JAVA实现
一,问题描述 给出一个无向图,指定无向图中某个顶点作为源点.求出图中所有顶点到源点的最短路径. 无向图的最短路径其实是源点到该顶点的最少边的数目. 本文假设图的信息保存在文件中,通过读取文件来构造图. ...
- 无向图的最短路径算法JAVA实现(转)
一,问题描述 给出一个无向图,指定无向图中某个顶点作为源点.求出图中所有顶点到源点的最短路径. 无向图的最短路径其实是源点到该顶点的最少边的数目. 本文假设图的信息保存在文件中,通过读取文件来构造图. ...
随机推荐
- python 新手遇到的问题
作为新手,我把之前遇到的问题贴出来 错误提示1: TypeError: unbound method a() must be called with A instance as first argum ...
- UI神器-SOUI
前言 在Windows平台上开发客户端产品是一个非常痛苦的过程,特别是还要用C++的时候.尽管很多语言很多方法都可以开发Windows桌面程序,目前国内流行的客户端产品都是C++开发的,比如QQ,YY ...
- html学习第二天—— 第九、十章——CSS的继承、层叠和特殊性+CSS格式化排版
继承CSS的某些样式是具有继承性的,那么什么是继承呢?继承是一种规则,它允许样式不仅应用于某个特定html标签元素,而且应用于其后代.比如下面代码:如某种颜色应用于p标签,这个颜色设置不仅应用p标签, ...
- node - glob模块
node的glob模块允许你使用 *等符号, 来写一个glob规则,像在shell里一样,获取匹配对应规则的文件. 这个glob工具基于javascript.它使用了 minimatch 库来进行匹配 ...
- codeforces346 Div.2 A.Round House
课间水一水,CCF备战 package com.company.cf346; import java.io.InputStreamReader; import java.util.Scanner; / ...
- Asia Hong Kong Regional Contest 2016
A. Colourful Graph 可以在$2n$步之内实现交换任意两个点的颜色,然后就可以构造出方案. #include <bits/stdc++.h> using namespace ...
- Logical query-processing phases
Logical query-processing phases in brief (1) FROM This phase identifies the query’s source tables an ...
- BZOJ‘s Usaco 奶牛题集锦
1230 线段树 1231 状压DP 1232 最小生成树 1527 贪心 1600 打表找规律 1601 最小生成树 1602 prime 1606 DP 1607 筛法 1609 DP 1610 ...
- 【WEB】一个简单的WEB服务器
WEB 服务器如何工作的? HTTP(HyperText Transfer Protocol)是一套计算机通过网络进行通信的规则.计算机专家设计出HTTP,使HTTP客户(如Web浏览器)能够从H ...
- [Android] Shape背景制作半圆或半边框
实现原理使用layer-list对shape进行叠加显示. 直接上代码: <layer-list xmlns:android="http://schemas.android.com/a ...