-
Notifications
You must be signed in to change notification settings - Fork 0
/
dag.go
105 lines (100 loc) · 1.75 KB
/
dag.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package DAG_Rider
type Round int
type Wave int
type DAG struct {
Round map[Round][]*Vertex
}
func (dag *DAG) Exist(v *Vertex) bool {
for _,ver := range dag.Round[v.Round] {
if v.Cmp(ver) == 0 {
return true
}
}
return false
}
// Path checks if it is possible to go from v to u through strong or weak edges
func (dag *DAG) Path(v,u *Vertex) bool {
if !dag.Exist(v) || !dag.Exist(u) {
return false
}
if v.Round < u.Round {
return false
}
if v.Round == u.Round {
if v.Cmp(u) == 0 {
return true
}else{
return false
}
}
vis := make(map[*Vertex]bool)
st := VertexStack{}
st.Push(v)
vis[v]=true
for !st.Empty() {
cur,_ := st.Pop()
for _,se := range cur.StrongEdges {
to := se.To
if _,fd := vis[to]; !fd {
if u.Cmp(to) == 0 {
return true
}
if to.Round > u.Round {
st.Push(to)
}
}
}
for _,we := range cur.StrongEdges {
to := we.To
if _,fd := vis[to]; !fd {
if u.Cmp(to) == 0 {
return true
}
if to.Round > u.Round {
st.Push(to)
}
}
}
}
return false
}
// StrongPath checks if it is possible to go from v to u through strong edges
func (dag *DAG) StrongPath(v,u *Vertex) bool {
if !dag.Exist(v) || !dag.Exist(u) {
return false
}
if v.Round < u.Round {
return false
}
if v.Round == u.Round {
if v.Cmp(u) == 0 {
return true
}else{
return false
}
}
vis := make(map[*Vertex]bool)
st := VertexStack{}
st.Push(v)
vis[v]=true
for !st.Empty() {
cur,_ := st.Pop()
for _,se := range cur.StrongEdges {
to := se.To
if _,fd := vis[to]; !fd {
if u.Cmp(to) == 0 {
return true
}
if to.Round > u.Round {
st.Push(to)
}
}
}
}
for _,se := range v.StrongEdges {
if dag.StrongPath(se.To, u) {
return true
}
}
return false
}