Skip to content

Instantly share code, notes, and snippets.

@michalmonday
Last active March 18, 2022 12:39
Show Gist options
  • Save michalmonday/af44755ae339feecbcd5afc3cb25d6a6 to your computer and use it in GitHub Desktop.
Save michalmonday/af44755ae339feecbcd5afc3cb25d6a6 to your computer and use it in GitHub Desktop.
Detect cycle in an undirected graph (python)
#python3
# It's simpler version of the example posted at:
# https://www.geeksforgeeks.org/union-find/
class Graph:
edges = set()
def add_edge(self, src, dst):
'''Each edge has 2 vertices: source and destination.'''
self.edges.add( (src,dst) )
def get_root(self, vertex):
'''Recursive function to get root vertex.'''
if self.parents[vertex] != -1:
return self.get_root(self.parents[vertex])
return vertex
def is_cyclic(self):
self.parents = dict()
# init parents of all vertices to -1
for src, dst in self.edges:
self.parents[src] = -1
self.parents[dst] = -1
# src and dst are vertices, e.g. src='a', dst='b'
for src, dst in self.edges:
x = self.get_root(src)
y = self.get_root(dst)
if x == y:
return True
self.parents[x] = y
''' Graph visualised:
a - b - c - d - e
| |
V - W - X - Y - Z
'''
g = Graph()
# 1st separate "line" of vertices connected together (marked with lower-case).
g.add_edge('a', 'b')
g.add_edge('b', 'c')
g.add_edge('c', 'd')
g.add_edge('d', 'e')
# 2nd separate "line" of vertices connected together (marked with upper-case).
g.add_edge('V', 'W')
g.add_edge('W', 'X')
g.add_edge('X', 'Y')
g.add_edge('Y', 'Z')
# Bridge between these 2 lines (forming closed cycle).
g.add_edge('b', 'W')
g.add_edge('c', 'X')
# Commenting-out 1 of the lines above should result
# in "Graph does not contain cycle" message.
if g.is_cyclic():
print ("Graph contains cycle")
else :
print ("Graph does not contain cycle ")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment