-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDirectedCycle.cpp
104 lines (87 loc) · 2.2 KB
/
DirectedCycle.cpp
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include "DirectedCycle.h"
DirectedCycle::DirectedCycle() {}
DirectedCycle::DirectedCycle(const Digraph& G) :
marked_(new bool[G.V()]()), onStack_(new bool[G.V()]()), edgeTo_(new int[G.V()]()), V_(G.V()) {
for (int v = 0; v < V_; v++)
if (!marked_[v]) dfs(G, v);
}
DirectedCycle::~DirectedCycle() {
delete[] marked_;
delete[] edgeTo_;
delete[] onStack_;
}
DirectedCycle::DirectedCycle(const DirectedCycle& other) :
marked_(new bool[other.V_]()), onStack_(new bool[other.V_]()), edgeTo_(new int[other.V_]()), cycle_(other.cycle_), V_(other.V_) {
for (int i = 0; i < V_; i++) {
marked_[i] = other.marked_[i];
edgeTo_[i] = other.edgeTo_[i];
onStack_[i] = other.onStack_[i];
}
}
DirectedCycle& DirectedCycle::operator=(const DirectedCycle& other) {
if (&other == this) return *this;
// Free memory
delete[] marked_;
delete[] edgeTo_;
delete[] onStack_;
// Allocate new memory
bool* tmarked = new bool[other.V_]();
int* tedgeTo = new int[other.V_]();
bool* tonStack = new bool[other.V_];
// Copy elements
for (int i = 0; i < other.V_; i++) {
marked_[i] = other.marked_[i];
edgeTo_[i] = other.edgeTo_[i];
onStack_[i] = other.onStack_[i];
}
// Reassign variables
V_ = other.V_;
marked_ = tmarked;
edgeTo_ = tedgeTo;
onStack_ = tonStack;
cycle_ = other.cycle_;
return *this;
}
void DirectedCycle::dfs(const Digraph& G, int v) {
onStack_[v] = true;
marked_[v] = true;
for (int w : G.adj(v)) {
// short circuit if directed cycle found
if (cycle_.size() != 0) return;
// found new vertex, so recur
else if (!marked_[w]) {
edgeTo_[w] = v;
dfs(G, w);
}
// trace back directed cycle
else if (onStack_[w]) {
for (int x = v; x != w; x = edgeTo_[x]) {
cycle_.addFirst(x);
}
cycle_.addFirst(w);
cycle_.addFirst(v);
}
}
onStack_[v] = false;
}
bool DirectedCycle::hasCycle() {
return cycle_.size() != 0;
}
Deque<int> DirectedCycle::cycle() {
return cycle_;
}
bool DirectedCycle::check(const Digraph& G) {
if (hasCycle()) {
// verify cycle
int first = -1, last = -1;
for (int v : cycle_) {
if (first == -1) first = v;
last = v;
}
if (first != last) {
printf("cycle begins with %d and ends with %d\n", first, last);
return false;
}
}
return true;
}