forked from shellfly/algo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathacyclic_sp.go
56 lines (48 loc) · 1.04 KB
/
acyclic_sp.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
package algs4
// AcyclicSP ...
type AcyclicSP struct {
distTo []float32
edgeTo []*DirectedEdge
}
// NewAcyclicSP ...
func NewAcyclicSP(g *EdgeWeightedDigraph, s int) *AcyclicSP {
edgeTo := make([]*DirectedEdge, g.V())
distTo := make([]float32, g.V())
for v := 0; v < g.V(); v++ {
distTo[v] = PositiveInfinity
}
distTo[s] = 0.0
a := &AcyclicSP{distTo, edgeTo}
top := NewEWDTopological(g)
for _, e := range top.Order() {
a.relax(e)
}
return a
}
func (a *AcyclicSP) relax(e *DirectedEdge) {
v := e.From()
w := e.To()
if a.distTo[w] > a.distTo[v]+e.Weight() {
a.distTo[w] = a.distTo[v] + e.Weight()
a.edgeTo[w] = e
}
}
// DistTo ...
func (a *AcyclicSP) DistTo(v int) float32 {
return a.distTo[v]
}
// HasPathTo ...
func (a *AcyclicSP) HasPathTo(v int) bool {
return a.distTo[v] < PositiveInfinity
}
// PathTo ...
func (a *AcyclicSP) PathTo(v int) (edges []*DirectedEdge) {
if !a.HasPathTo(v) {
return nil
}
for e := a.edgeTo[v]; e != nil; e = a.edgeTo[e.From()] {
// stack
edges = append([]*DirectedEdge{e}, edges...)
}
return
}