-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgraph.py
56 lines (46 loc) · 1.54 KB
/
graph.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
"""
No longer used.
"""
class Graph():
"""
Represents a standard directed graph that allows cycle detection.
The number of nodes must be fixed at the time of graph creation.
Edges can (and should) be added after the graph is initialized
"""
def __init__(self, vertices):
self.V = vertices
self.E = {v:set() for v in vertices}
def add_edge(self, from_node, to_node):
self.E[from_node].add(to_node)
def neighbors(self, v):
return self.E[v]
def reachable_from(self, start):
visited = {v:False for v in self.V}
reachable = set()
# Launches DFS from a given node
def explore(v):
visited[v] = True
reachable.add(v)
for n in self.neighbors(v):
if not visited[n]:
explore(n)
# Launch DFS from just the start and return
explore(start)
return reachable
def has_cycle(self):
visited = {v:False for v in self.V}
has_cycle = False
# Launches DFS from a given node
def explore(v):
nonlocal has_cycle
visited[v] = True
for n in self.neighbors(v):
if not visited[n]:
explore(n)
else:
has_cycle = True
# Launches DFS for each connected component in the graph
for node in self.V:
if not visited[node]:
explore(node)
return has_cycle