-
Notifications
You must be signed in to change notification settings - Fork 10
/
detect_cycle.go
87 lines (67 loc) · 1.24 KB
/
detect_cycle.go
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
package main
import (
"container/list"
"fmt"
)
func detectCycles(n int, g graph) {
visited := make([]bool, n)
parents := make([]int, n)
for ix := range parents {
parents[ix] = -1
}
c := make(map[edge]struct{})
var count int
for ix := 0; ix < n; ix++ {
if !visited[ix] {
dfs(ix, g, parents, visited, c)
count += len(c)
}
}
fmt.Printf("number of cycles: %d\n", count)
}
type edge struct {
src, dst int
}
func dfs(r int, g graph, parents []int, visited []bool, c map[edge]struct{}) {
visited[r] = true
for e := g[r].Front(); e != nil; e = e.Next() {
adj := e.Value.(int)
if visited[adj] { // new cycle
if parents[r] != adj {
a, b := edge{r, adj}, edge{adj, r}
_, containsA := c[a]
if _, containsB := c[b]; !containsA && !containsB {
c[a] = struct{}{}
}
}
} else {
parents[adj] = r
dfs(adj, g, parents, visited, c)
}
}
}
/*
0 -- 1 -- 3
\ | /
\ | /
2
*/
func main() {
const n = 4
g := make(graph, n)
for ix := range g {
g[ix] = list.New()
}
g[0].PushBack(1)
g[0].PushBack(2)
g[1].PushBack(0)
g[1].PushBack(2)
g[1].PushBack(3)
g[2].PushBack(0)
g[2].PushBack(1)
g[2].PushBack(3)
g[3].PushBack(2)
g[3].PushBack(1)
detectCycles(n, g)
}
type graph []*list.List