【转】并查集 - 检测图(无向图)是否包含环
转载:
https://www.geeksforgeeks.org/union-find/
并查集(1)-判断无向图是否存在环
并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。集就是让每个元素构成一个单元素的集合,也就是按一定顺序将属于同一组的元素所在的集合合并。
- Find:确定元素属于哪一个子集。它可以被用来确定两个元素是否属于同一子集合。
- Union:将两个子集合并成同一个集合。
其实判断一个图是否存在环已经有相应的算法,此文用并查集来判断一个图是否有环。
我们可以用一个一维数组parent[] 来记录子集合。
看下面这个图:
0 | \ | \ 1-----2
对每一条边的两个顶点加入集合,发现两个相同的顶点在一个子集合中,就说明存在环。
初始化:parent[n] 的每个元素都为-1,共有n个子集合,表示集合只有当前顶点一个元素。
0 1 2 -1 -1 -1
然后逐个处理每条边。
边0-1:我们找到两个子集合 0 和1,因为他们在不同的子集合,现在需要合并他们(Union). 把其中一个子集合作为对方的父集合.
0 1 2 <----- 1 成为 0 的 父集合 (1 现在代表集合 {0, 1}) 1 -1 -1
边0-2:1属于属于子集合1,2属于子集合2,因此合并他们。
0 1 2 <----- 2 作为 1的父集合 (2 现在代表集合 {0, 1, 2}) 1 2 -1
边0-2: 0是在子集和2和2也是在子集合2, 因为 0->1->2 // 1 是0 父集合 并且 2 是1的父集合 。因此,找到了环。
Python代码:
1 # Python Program for union-find algorithm to detect cycle in a undirected graph 2 # we have one egde for any two vertex i.e 1-2 is either 1-2 or 2-1 but not both 3 4 from collections import defaultdict 5 6 #This class represents a undirected graph using adjacency list representation 7 class Graph: 8 9 def __init__(self,vertices): 10 self.V= vertices #No. of vertices 11 self.graph = defaultdict(list) # default dictionary to store graph 12 13 14 # function to add an edge to graph 15 def addEdge(self,u,v): 16 self.graph[u].append(v) 17 18 # A utility function to find the subset of an element i 19 def find_parent(self, parent,i): 20 if parent[i] == -1: 21 return i 22 if parent[i]!= -1: 23 return self.find_parent(parent,parent[i]) 24 25 # A utility function to do union of two subsets 26 def union(self,parent,x,y): 27 x_set = self.find_parent(parent, x) 28 y_set = self.find_parent(parent, y) 29 parent[x_set] = y_set 30 31 32 33 # The main function to check whether a given graph 34 # contains cycle or not 35 def isCyclic(self): 36 37 # Allocate memory for creating V subsets and 38 # Initialize all subsets as single element sets 39 parent = [-1]*(self.V) 40 41 # Iterate through all edges of graph, find subset of both 42 # vertices of every edge, if both subsets are same, then 43 # there is cycle in graph. 44 for i in self.graph: 45 for j in self.graph[i]: 46 x = self.find_parent(parent, i) 47 y = self.find_parent(parent, j) 48 if x == y: 49 return True 50 self.union(parent,x,y) 51 52 53 # Create a graph given in the above diagram 54 g = Graph(3) 55 g.addEdge(0, 1) 56 g.addEdge(1, 2) 57 g.addEdge(2, 0) 58 59 if g.isCyclic(): 60 print "Graph contains cycle" 61 else : 62 print "Graph does not contain cycle " 63 64 #This code is contributed by Neelam Yadav
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具