File tree 2 files changed +73
-0
lines changed
2 files changed +73
-0
lines changed Original file line number Diff line number Diff line change @@ -62,6 +62,7 @@ Try to keep the interface and variable name consistent with the original book wh
62
62
* [ DegreesOfSeparation] ( algs4/degrees_of_separation.py )
63
63
* [ Digraph] ( algs4/digraph.py )
64
64
* [ DirectedDFS] ( algs4/directed_dfs.py )
65
+ * [ DirectedCycle] ( algs4/directed_cycle.py )
65
66
66
67
* 5 STRING
67
68
Original file line number Diff line number Diff line change
1
+ """
2
+ Execution: python directed_cycle.py input.txt
3
+ Data files: https://algs4.cs.princeton.edu/42digraph/tinyDG.txt
4
+ https://algs4.cs.princeton.edu/42digraph/tinyDAG.txt
5
+
6
+ Finds a directed cycle in a digraph.
7
+ Runs in O(E + V) time.
8
+
9
+ % python directed_cycle.py tinyDG.txt
10
+ Directed cycle: 3 5 4 3
11
+
12
+ % python directed_cycle.py tinyDAG.txt
13
+ No directed cycle
14
+
15
+ """
16
+ from algs4 .stack import Stack
17
+ from algs4 .digraph import Digraph
18
+
19
+
20
+ class DirectedCycle :
21
+
22
+ def __init__ (self , G ):
23
+ self ._marked = [False for _ in range (G .V )]
24
+ self .edge_to = [False for _ in range (G .V )]
25
+ self .on_stack = [False for _ in range (G .V )]
26
+ self .cycle = None
27
+ for v in range (G .V ):
28
+ if not self ._marked [v ]:
29
+ self .dfs (G , v )
30
+
31
+ def dfs (self , G , v ):
32
+ self ._marked [v ] = True
33
+ self .on_stack [v ] = True
34
+
35
+ for w in G .adj [v ]:
36
+ if self .has_cycle ():
37
+ return
38
+ if not self ._marked [w ]:
39
+ self .edge_to [w ] = v
40
+ self .dfs (G , w )
41
+ elif self .on_stack [w ]:
42
+ self .cycle = Stack ()
43
+ x = v
44
+ while x != w :
45
+ self .cycle .push (x )
46
+ x = self .edge_to [x ]
47
+ self .cycle .push (w )
48
+ self .cycle .push (v )
49
+ self .on_stack [v ] = False
50
+
51
+ def marked (self , v ):
52
+ return self ._marked [v ]
53
+
54
+ def has_cycle (self ):
55
+ return self .cycle is not None
56
+
57
+ if __name__ == '__main__' :
58
+ import sys
59
+ f = open (sys .argv [1 ])
60
+ V = int (f .readline ())
61
+ E = int (f .readline ())
62
+ g = Digraph (V )
63
+ for i in range (E ):
64
+ v , w = f .readline ().split ()
65
+ g .add_edge (v , w )
66
+
67
+ finder = DirectedCycle (g )
68
+ if finder .has_cycle ():
69
+ for v in finder .cycle :
70
+ print (v , end = " " )
71
+ else :
72
+ print ("No directed cycle" )
You can’t perform that action at this time.
0 commit comments