diff --git a/vendor/github.com/gyuho/goraph/.travis.yml b/vendor/github.com/gyuho/goraph/.travis.yml
new file mode 100644
index 0000000..4228e24
--- /dev/null
+++ b/vendor/github.com/gyuho/goraph/.travis.yml
@@ -0,0 +1,11 @@
+language: go
+
+sudo: false
+
+go:
+- 1.6
+- tip
+
+script:
+- ./test
+
diff --git a/vendor/github.com/gyuho/goraph/LICENSE b/vendor/github.com/gyuho/goraph/LICENSE
new file mode 100644
index 0000000..f7303ba
--- /dev/null
+++ b/vendor/github.com/gyuho/goraph/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Gyu-Ho Lee
+Copyright (c) 2016 Google Inc
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/gyuho/goraph/README.md b/vendor/github.com/gyuho/goraph/README.md
new file mode 100644
index 0000000..0b5b590
--- /dev/null
+++ b/vendor/github.com/gyuho/goraph/README.md
@@ -0,0 +1,32 @@
+## goraph [![Build Status](https://img.shields.io/travis/gyuho/goraph.svg?style=flat-square)](https://travis-ci.org/gyuho/goraph) [![Godoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://godoc.org/github.com/gyuho/goraph)
+
+Package goraph implements graph data structure and algorithms.
+
+```
+go get -v gopkg.in/gyuho/goraph.v2;
+```
+
+<br>
+I have tutorials and visualizations of graph, tree algorithms:
+
+- [**_Binary search tree_**](https://github.com/gyuho/learn/tree/master/doc/binary_search_tree)
+- [**_Go: heap, priority queue_**](https://github.com/gyuho/learn/tree/master/doc/go_heap_priority_queue)
+- [**_Go: red black tree_**](https://github.com/gyuho/learn/tree/master/doc/go_red_black_tree)
+- [**_Go: b-tree_**](https://github.com/gyuho/learn/tree/master/doc/go_b_tree)
+- [**_Go: graph, interface_**](https://github.com/gyuho/learn/tree/master/doc/go_graph_interface)
+- [**_Go: graph, traversal_**](https://github.com/gyuho/learn/tree/master/doc/go_graph_traversal)
+- [**_Go: graph, shortest path_**](https://github.com/gyuho/learn/tree/master/doc/go_graph_shortest_path)
+- [**_Go: graph, topological sort_**](https://github.com/gyuho/learn/tree/master/doc/go_graph_topological_sort)
+- [**_Go: graph, minimum spanning tree_**](https://github.com/gyuho/learn/tree/master/doc/go_graph_minimum_spanning_tree)
+- [**_Go: graph, strongly connected components_**](https://github.com/gyuho/learn/tree/master/doc/go_graph_strongly_connected_components)
+
+<br>
+For fast query and retrieval, please check out  <a href="http://google-opensource.blogspot.co.uk/2014/06/cayley-graphs-in-go.html" target="_blank">Cayley</a>.
+
+
+<br>
+<a href="http://www.youtube.com/watch?v=ImMnYq2zP4Y" target="_blank"><img src="http://img.youtube.com/vi/ImMnYq2zP4Y/0.jpg"></a>
+
+- <a href="https://www.youtube.com/channel/UCWzSgIp_DYRQnEsJuH32Fww" target="_blank">Please visit my YouTube Channel</a>
+- <a href="https://www.youtube.com/watch?v=NdfIfxTsVDo&list=PLT6aABhFfinvsSn1H195JLuHaXNS6UVhf" target="_blank">`Tree`, `Graph` Theory Algorithms (Playlist)</a>
+- <a href="https://www.youtube.com/watch?v=ImMnYq2zP4Y&list=PLT6aABhFfinvsSn1H195JLuHaXNS6UVhf&index=4" target="_blank">`Graph` : BFS, DFS</a>
diff --git a/vendor/github.com/gyuho/goraph/disjoint_set.go b/vendor/github.com/gyuho/goraph/disjoint_set.go
new file mode 100644
index 0000000..3a8085f
--- /dev/null
+++ b/vendor/github.com/gyuho/goraph/disjoint_set.go
@@ -0,0 +1,67 @@
+package goraph
+
+import "sync"
+
+// DisjointSet implements disjoint set.
+// (https://en.wikipedia.org/wiki/Disjoint-set_data_structure)
+type DisjointSet struct {
+	represent string
+	members   map[string]struct{}
+}
+
+// Forests is a set of DisjointSet.
+type Forests struct {
+	mu   sync.Mutex // guards the following
+	data map[*DisjointSet]struct{}
+}
+
+// NewForests creates a new Forests.
+func NewForests() *Forests {
+	set := &Forests{}
+	set.data = make(map[*DisjointSet]struct{})
+	return set
+}
+
+// MakeDisjointSet creates a DisjointSet.
+func MakeDisjointSet(forests *Forests, name string) {
+	newDS := &DisjointSet{}
+	newDS.represent = name
+	members := make(map[string]struct{})
+	members[name] = struct{}{}
+	newDS.members = members
+	forests.mu.Lock()
+	defer forests.mu.Unlock()
+	forests.data[newDS] = struct{}{}
+}
+
+// FindSet returns the DisjointSet with the represent name.
+func FindSet(forests *Forests, name string) *DisjointSet {
+	forests.mu.Lock()
+	defer forests.mu.Unlock()
+	for data := range forests.data {
+		if data.represent == name {
+			return data
+		}
+		for k := range data.members {
+			if k == name {
+				return data
+			}
+		}
+	}
+	return nil
+}
+
+// Union unions two DisjointSet, with ds1's represent.
+func Union(forests *Forests, ds1, ds2 *DisjointSet) {
+	newDS := &DisjointSet{}
+	newDS.represent = ds1.represent
+	newDS.members = ds1.members
+	for k := range ds2.members {
+		newDS.members[k] = struct{}{}
+	}
+	forests.mu.Lock()
+	defer forests.mu.Unlock()
+	forests.data[newDS] = struct{}{}
+	delete(forests.data, ds1)
+	delete(forests.data, ds2)
+}
diff --git a/vendor/github.com/gyuho/goraph/doc.go b/vendor/github.com/gyuho/goraph/doc.go
new file mode 100644
index 0000000..191d299
--- /dev/null
+++ b/vendor/github.com/gyuho/goraph/doc.go
@@ -0,0 +1,2 @@
+// Package goraph implements graph data structure and algorithms.
+package goraph // import "github.com/gyuho/goraph"
diff --git a/vendor/github.com/gyuho/goraph/graph.go b/vendor/github.com/gyuho/goraph/graph.go
new file mode 100644
index 0000000..87f87c5
--- /dev/null
+++ b/vendor/github.com/gyuho/goraph/graph.go
@@ -0,0 +1,503 @@
+package goraph
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"io"
+	"sync"
+)
+
+// ID is unique identifier.
+type ID interface {
+	// String returns the string ID.
+	String() string
+}
+
+type StringID string
+
+func (s StringID) String() string {
+	return string(s)
+}
+
+// Node is vertex. The ID must be unique within the graph.
+type Node interface {
+	// ID returns the ID.
+	ID() ID
+	String() string
+}
+
+type node struct {
+	id string
+}
+
+var nodeCnt uint64
+
+func NewNode(id string) Node {
+	return &node{
+		id: id,
+	}
+}
+
+func (n *node) ID() ID {
+	return StringID(n.id)
+}
+
+func (n *node) String() string {
+	return n.id
+}
+
+// Edge connects between two Nodes.
+type Edge interface {
+	Source() Node
+	Target() Node
+	Weight() float64
+	String() string
+}
+
+// edge is an Edge from Source to Target.
+type edge struct {
+	src Node
+	tgt Node
+	wgt float64
+}
+
+func NewEdge(src, tgt Node, wgt float64) Edge {
+	return &edge{
+		src: src,
+		tgt: tgt,
+		wgt: wgt,
+	}
+}
+
+func (e *edge) Source() Node {
+	return e.src
+}
+
+func (e *edge) Target() Node {
+	return e.tgt
+}
+
+func (e *edge) Weight() float64 {
+	return e.wgt
+}
+
+func (e *edge) String() string {
+	return fmt.Sprintf("%s -- %.3f -→ %s\n", e.src, e.wgt, e.tgt)
+}
+
+type EdgeSlice []Edge
+
+func (e EdgeSlice) Len() int           { return len(e) }
+func (e EdgeSlice) Less(i, j int) bool { return e[i].Weight() < e[j].Weight() }
+func (e EdgeSlice) Swap(i, j int)      { e[i], e[j] = e[j], e[i] }
+
+// Graph describes the methods of graph operations.
+// It assumes that the identifier of a Node is unique.
+// And weight values is float64.
+type Graph interface {
+	// Init initializes a Graph.
+	Init()
+
+	// GetNodeCount returns the total number of nodes.
+	GetNodeCount() int
+
+	// GetNode finds the Node. It returns nil if the Node
+	// does not exist in the graph.
+	GetNode(id ID) Node
+
+	// GetNodes returns a map from node ID to
+	// empty struct value. Graph does not allow duplicate
+	// node ID or name.
+	GetNodes() map[ID]Node
+
+	// AddNode adds a node to a graph, and returns false
+	// if the node already existed in the graph.
+	AddNode(nd Node) bool
+
+	// DeleteNode deletes a node from a graph.
+	// It returns true if it got deleted.
+	// And false if it didn't get deleted.
+	DeleteNode(id ID) bool
+
+	// AddEdge adds an edge from nd1 to nd2 with the weight.
+	// It returns error if a node does not exist.
+	AddEdge(id1, id2 ID, weight float64) error
+
+	// ReplaceEdge replaces an edge from id1 to id2 with the weight.
+	ReplaceEdge(id1, id2 ID, weight float64) error
+
+	// DeleteEdge deletes an edge from id1 to id2.
+	DeleteEdge(id1, id2 ID) error
+
+	// GetWeight returns the weight from id1 to id2.
+	GetWeight(id1, id2 ID) (float64, error)
+
+	// GetSources returns the map of parent Nodes.
+	// (Nodes that come towards the argument vertex.)
+	GetSources(id ID) (map[ID]Node, error)
+
+	// GetTargets returns the map of child Nodes.
+	// (Nodes that go out of the argument vertex.)
+	GetTargets(id ID) (map[ID]Node, error)
+
+	// String describes the Graph.
+	String() string
+}
+
+// graph is an internal default graph type that
+// implements all methods in Graph interface.
+type graph struct {
+	mu sync.RWMutex // guards the following
+
+	// idToNodes stores all nodes.
+	idToNodes map[ID]Node
+
+	// nodeToSources maps a Node identifer to sources(parents) with edge weights.
+	nodeToSources map[ID]map[ID]float64
+
+	// nodeToTargets maps a Node identifer to targets(children) with edge weights.
+	nodeToTargets map[ID]map[ID]float64
+}
+
+// newGraph returns a new graph.
+func newGraph() *graph {
+	return &graph{
+		idToNodes:     make(map[ID]Node),
+		nodeToSources: make(map[ID]map[ID]float64),
+		nodeToTargets: make(map[ID]map[ID]float64),
+		//
+		// without this
+		// panic: assignment to entry in nil map
+	}
+}
+
+// NewGraph returns a new graph.
+func NewGraph() Graph {
+	return newGraph()
+}
+
+func (g *graph) Init() {
+	// (X) g = newGraph()
+	// this only updates the pointer
+	//
+	//
+	// (X) *g = *newGraph()
+	// assignment copies lock value
+
+	g.idToNodes = make(map[ID]Node)
+	g.nodeToSources = make(map[ID]map[ID]float64)
+	g.nodeToTargets = make(map[ID]map[ID]float64)
+}
+
+func (g *graph) GetNodeCount() int {
+	g.mu.RLock()
+	defer g.mu.RUnlock()
+
+	return len(g.idToNodes)
+}
+
+func (g *graph) GetNode(id ID) Node {
+	g.mu.RLock()
+	defer g.mu.RUnlock()
+
+	return g.idToNodes[id]
+}
+
+func (g *graph) GetNodes() map[ID]Node {
+	g.mu.RLock()
+	defer g.mu.RUnlock()
+
+	return g.idToNodes
+}
+
+func (g *graph) unsafeExistID(id ID) bool {
+	_, ok := g.idToNodes[id]
+	return ok
+}
+
+func (g *graph) AddNode(nd Node) bool {
+	g.mu.Lock()
+	defer g.mu.Unlock()
+
+	if g.unsafeExistID(nd.ID()) {
+		return false
+	}
+
+	id := nd.ID()
+	g.idToNodes[id] = nd
+	return true
+}
+
+func (g *graph) DeleteNode(id ID) bool {
+	g.mu.Lock()
+	defer g.mu.Unlock()
+
+	if !g.unsafeExistID(id) {
+		return false
+	}
+
+	delete(g.idToNodes, id)
+
+	delete(g.nodeToTargets, id)
+	for _, smap := range g.nodeToTargets {
+		delete(smap, id)
+	}
+
+	delete(g.nodeToSources, id)
+	for _, smap := range g.nodeToSources {
+		delete(smap, id)
+	}
+
+	return true
+}
+
+func (g *graph) AddEdge(id1, id2 ID, weight float64) error {
+	g.mu.Lock()
+	defer g.mu.Unlock()
+
+	if !g.unsafeExistID(id1) {
+		return fmt.Errorf("%s does not exist in the graph.", id1)
+	}
+	if !g.unsafeExistID(id2) {
+		return fmt.Errorf("%s does not exist in the graph.", id2)
+	}
+
+	if _, ok := g.nodeToTargets[id1]; ok {
+		if v, ok2 := g.nodeToTargets[id1][id2]; ok2 {
+			g.nodeToTargets[id1][id2] = v + weight
+		} else {
+			g.nodeToTargets[id1][id2] = weight
+		}
+	} else {
+		tmap := make(map[ID]float64)
+		tmap[id2] = weight
+		g.nodeToTargets[id1] = tmap
+	}
+	if _, ok := g.nodeToSources[id2]; ok {
+		if v, ok2 := g.nodeToSources[id2][id1]; ok2 {
+			g.nodeToSources[id2][id1] = v + weight
+		} else {
+			g.nodeToSources[id2][id1] = weight
+		}
+	} else {
+		tmap := make(map[ID]float64)
+		tmap[id1] = weight
+		g.nodeToSources[id2] = tmap
+	}
+
+	return nil
+}
+
+func (g *graph) ReplaceEdge(id1, id2 ID, weight float64) error {
+	g.mu.Lock()
+	defer g.mu.Unlock()
+
+	if !g.unsafeExistID(id1) {
+		return fmt.Errorf("%s does not exist in the graph.", id1)
+	}
+	if !g.unsafeExistID(id2) {
+		return fmt.Errorf("%s does not exist in the graph.", id2)
+	}
+
+	if _, ok := g.nodeToTargets[id1]; ok {
+		g.nodeToTargets[id1][id2] = weight
+	} else {
+		tmap := make(map[ID]float64)
+		tmap[id2] = weight
+		g.nodeToTargets[id1] = tmap
+	}
+	if _, ok := g.nodeToSources[id2]; ok {
+		g.nodeToSources[id2][id1] = weight
+	} else {
+		tmap := make(map[ID]float64)
+		tmap[id1] = weight
+		g.nodeToSources[id2] = tmap
+	}
+	return nil
+}
+
+func (g *graph) DeleteEdge(id1, id2 ID) error {
+	g.mu.Lock()
+	defer g.mu.Unlock()
+
+	if !g.unsafeExistID(id1) {
+		return fmt.Errorf("%s does not exist in the graph.", id1)
+	}
+	if !g.unsafeExistID(id2) {
+		return fmt.Errorf("%s does not exist in the graph.", id2)
+	}
+
+	if _, ok := g.nodeToTargets[id1]; ok {
+		if _, ok := g.nodeToTargets[id1][id2]; ok {
+			delete(g.nodeToTargets[id1], id2)
+		}
+	}
+	if _, ok := g.nodeToSources[id2]; ok {
+		if _, ok := g.nodeToSources[id2][id1]; ok {
+			delete(g.nodeToSources[id2], id1)
+		}
+	}
+	return nil
+}
+
+func (g *graph) GetWeight(id1, id2 ID) (float64, error) {
+	g.mu.RLock()
+	defer g.mu.RUnlock()
+
+	if !g.unsafeExistID(id1) {
+		return 0, fmt.Errorf("%s does not exist in the graph.", id1)
+	}
+	if !g.unsafeExistID(id2) {
+		return 0, fmt.Errorf("%s does not exist in the graph.", id2)
+	}
+
+	if _, ok := g.nodeToTargets[id1]; ok {
+		if v, ok := g.nodeToTargets[id1][id2]; ok {
+			return v, nil
+		}
+	}
+	return 0.0, fmt.Errorf("there is no edge from %s to %s", id1, id2)
+}
+
+func (g *graph) GetSources(id ID) (map[ID]Node, error) {
+	g.mu.RLock()
+	defer g.mu.RUnlock()
+
+	if !g.unsafeExistID(id) {
+		return nil, fmt.Errorf("%s does not exist in the graph.", id)
+	}
+
+	rs := make(map[ID]Node)
+	if _, ok := g.nodeToSources[id]; ok {
+		for n := range g.nodeToSources[id] {
+			rs[n] = g.idToNodes[n]
+		}
+	}
+	return rs, nil
+}
+
+func (g *graph) GetTargets(id ID) (map[ID]Node, error) {
+	g.mu.RLock()
+	defer g.mu.RUnlock()
+
+	if !g.unsafeExistID(id) {
+		return nil, fmt.Errorf("%s does not exist in the graph.", id)
+	}
+
+	rs := make(map[ID]Node)
+	if _, ok := g.nodeToTargets[id]; ok {
+		for n := range g.nodeToTargets[id] {
+			rs[n] = g.idToNodes[n]
+		}
+	}
+	return rs, nil
+}
+
+func (g *graph) String() string {
+	g.mu.RLock()
+	defer g.mu.RUnlock()
+
+	buf := new(bytes.Buffer)
+	for id1, nd1 := range g.idToNodes {
+		nmap, _ := g.GetTargets(id1)
+		for id2, nd2 := range nmap {
+			weight, _ := g.GetWeight(id1, id2)
+			fmt.Fprintf(buf, "%s -- %.3f -→ %s\n", nd1, weight, nd2)
+		}
+	}
+	return buf.String()
+}
+
+// NewGraphFromJSON returns a new Graph from a JSON file.
+// Here's the sample JSON data:
+//
+//	{
+//	    "graph_00": {
+//	        "S": {
+//	            "A": 100,
+//	            "B": 14,
+//	            "C": 200
+//	        },
+//	        "A": {
+//	            "S": 15,
+//	            "B": 5,
+//	            "D": 20,
+//	            "T": 44
+//	        },
+//	        "B": {
+//	            "S": 14,
+//	            "A": 5,
+//	            "D": 30,
+//	            "E": 18
+//	        },
+//	        "C": {
+//	            "S": 9,
+//	            "E": 24
+//	        },
+//	        "D": {
+//	            "A": 20,
+//	            "B": 30,
+//	            "E": 2,
+//	            "F": 11,
+//	            "T": 16
+//	        },
+//	        "E": {
+//	            "B": 18,
+//	            "C": 24,
+//	            "D": 2,
+//	            "F": 6,
+//	            "T": 19
+//	        },
+//	        "F": {
+//	            "D": 11,
+//	            "E": 6,
+//	            "T": 6
+//	        },
+//	        "T": {
+//	            "A": 44,
+//	            "D": 16,
+//	            "F": 6,
+//	            "E": 19
+//	        }
+//	    },
+//	}
+//
+func NewGraphFromJSON(rd io.Reader, graphID string) (Graph, error) {
+	js := make(map[string]map[string]map[string]float64)
+	dec := json.NewDecoder(rd)
+	for {
+		if err := dec.Decode(&js); err == io.EOF {
+			break
+		} else if err != nil {
+			return nil, err
+		}
+	}
+	if _, ok := js[graphID]; !ok {
+		return nil, fmt.Errorf("%s does not exist", graphID)
+	}
+	gmap := js[graphID]
+
+	g := newGraph()
+	for id1, mm := range gmap {
+		nd1 := g.GetNode(StringID(id1))
+		if nd1 == nil {
+			nd1 = NewNode(id1)
+			if ok := g.AddNode(nd1); !ok {
+				return nil, fmt.Errorf("%s already exists", nd1)
+			}
+		}
+		for id2, weight := range mm {
+			nd2 := g.GetNode(StringID(id2))
+			if nd2 == nil {
+				nd2 = NewNode(id2)
+				if ok := g.AddNode(nd2); !ok {
+					return nil, fmt.Errorf("%s already exists", nd2)
+				}
+			}
+			g.ReplaceEdge(nd1.ID(), nd2.ID(), weight)
+		}
+	}
+
+	return g, nil
+}
diff --git a/vendor/github.com/gyuho/goraph/minimum_spanning_tree.go b/vendor/github.com/gyuho/goraph/minimum_spanning_tree.go
new file mode 100644
index 0000000..a86e279
--- /dev/null
+++ b/vendor/github.com/gyuho/goraph/minimum_spanning_tree.go
@@ -0,0 +1,287 @@
+package goraph
+
+import (
+	"container/heap"
+	"math"
+	"sort"
+)
+
+// Kruskal finds the minimum spanning tree with disjoint-set data structure.
+// (http://en.wikipedia.org/wiki/Kruskal%27s_algorithm)
+//
+//	 0. Kruskal(G)
+//	 1.
+//	 2. 	A = ∅
+//	 3.
+//	 4. 	for each vertex v in G:
+//	 5. 		MakeDisjointSet(v)
+//	 6.
+//	 7. 	edges = get all edges
+//	 8. 	sort edges in ascending order of weight
+//	 9.
+//	10. 	for each edge (u, v) in edges:
+//	11. 		if FindSet(u) ≠ FindSet(v):
+//	12. 			A = A ∪ {(u, v)}
+//	13. 			Union(u, v)
+//	14.
+//	15. 	return A
+//
+func Kruskal(g Graph) (map[Edge]struct{}, error) {
+
+	// A = ∅
+	A := make(map[Edge]struct{})
+
+	// disjointSet maps a member Node to a represent.
+	// (https://en.wikipedia.org/wiki/Disjoint-set_data_structure)
+	forests := NewForests()
+
+	// for each vertex v in G:
+	for _, nd := range g.GetNodes() {
+		// MakeDisjointSet(v)
+		MakeDisjointSet(forests, nd.String())
+	}
+
+	// edges = get all edges
+	edges := []Edge{}
+	foundEdge := make(map[string]struct{})
+	for id1, nd1 := range g.GetNodes() {
+		tm, err := g.GetTargets(id1)
+		if err != nil {
+			return nil, err
+		}
+		for id2, nd2 := range tm {
+			weight, err := g.GetWeight(id1, id2)
+			if err != nil {
+				return nil, err
+			}
+			edge := NewEdge(nd1, nd2, weight)
+			if _, ok := foundEdge[edge.String()]; !ok {
+				edges = append(edges, edge)
+				foundEdge[edge.String()] = struct{}{}
+			}
+		}
+
+		sm, err := g.GetSources(id1)
+		if err != nil {
+			return nil, err
+		}
+		for id3, nd3 := range sm {
+			weight, err := g.GetWeight(id3, id1)
+			if err != nil {
+				return nil, err
+			}
+			edge := NewEdge(nd3, nd1, weight)
+			if _, ok := foundEdge[edge.String()]; !ok {
+				edges = append(edges, edge)
+				foundEdge[edge.String()] = struct{}{}
+			}
+		}
+	}
+
+	// sort edges in ascending order of weight
+	sort.Sort(EdgeSlice(edges))
+
+	// for each edge (u, v) in edges:
+	for _, edge := range edges {
+		// if FindSet(u) ≠ FindSet(v):
+		if FindSet(forests, edge.Source().String()).represent != FindSet(forests, edge.Target().String()).represent {
+
+			// A = A ∪ {(u, v)}
+			A[edge] = struct{}{}
+
+			// Union(u, v)
+			// overwrite v's represent with u's represent
+			Union(forests, FindSet(forests, edge.Source().String()), FindSet(forests, edge.Target().String()))
+		}
+	}
+
+	return A, nil
+}
+
+// Prim finds the minimum spanning tree with min-heap (priority queue).
+// (http://en.wikipedia.org/wiki/Prim%27s_algorithm)
+//
+//	 0. Prim(G, source)
+//	 1.
+//	 2. 	let Q be a priority queue
+//	 3. 	distance[source] = 0
+//	 4.
+//	 5. 	for each vertex v in G:
+//	 6.
+//	 7. 		if v ≠ source:
+//	 8. 			distance[v] = ∞
+//	 9. 			prev[v] = undefined
+//	10.
+//	11. 		Q.add_with_priority(v, distance[v])
+//	12.
+//	13.
+//	14. 	while Q is not empty:
+//	15.
+//	16. 		u = Q.extract_min()
+//	17.
+//	18. 		for each adjacent vertex v of u:
+//	19.
+//	21. 			if v ∈ Q and distance[v] > weight(u, v):
+//	22. 				distance[v] = weight(u, v)
+//	23. 				prev[v] = u
+//	24. 				Q.decrease_priority(v, weight(u, v))
+//	25.
+//	26.
+//	27. 	return tree from prev
+//
+func Prim(g Graph, src ID) (map[Edge]struct{}, error) {
+
+	// let Q be a priority queue
+	minHeap := &nodeDistanceHeap{}
+
+	// distance[source] = 0
+	distance := make(map[ID]float64)
+	distance[src] = 0.0
+
+	// for each vertex v in G:
+	for id := range g.GetNodes() {
+
+		// if v ≠ src:
+		if id != src {
+			// distance[v] = ∞
+			distance[id] = math.MaxFloat64
+
+			// prev[v] = undefined
+			// prev[v] = ""
+		}
+
+		// Q.add_with_priority(v, distance[v])
+		nds := nodeDistance{}
+		nds.id = id
+		nds.distance = distance[id]
+
+		heap.Push(minHeap, nds)
+	}
+
+	heap.Init(minHeap)
+	prev := make(map[ID]ID)
+
+	// while Q is not empty:
+	for minHeap.Len() != 0 {
+
+		// u = Q.extract_min()
+		u := heap.Pop(minHeap).(nodeDistance)
+		uID := u.id
+
+		// for each adjacent vertex v of u:
+		tm, err := g.GetTargets(uID)
+		if err != nil {
+			return nil, err
+		}
+		for vID := range tm {
+
+			isExist := false
+			for _, one := range *minHeap {
+				if vID == one.id {
+					isExist = true
+					break
+				}
+			}
+
+			// weight(u, v)
+			weight, err := g.GetWeight(uID, vID)
+			if err != nil {
+				return nil, err
+			}
+
+			// if v ∈ Q and distance[v] > weight(u, v):
+			if isExist && distance[vID] > weight {
+
+				// distance[v] = weight(u, v)
+				distance[vID] = weight
+
+				// prev[v] = u
+				prev[vID] = uID
+
+				// Q.decrease_priority(v, weight(u, v))
+				minHeap.updateDistance(vID, weight)
+				heap.Init(minHeap)
+			}
+		}
+
+		sm, err := g.GetSources(uID)
+		if err != nil {
+			return nil, err
+		}
+		vID := uID
+		for uID := range sm {
+
+			isExist := false
+			for _, one := range *minHeap {
+				if vID == one.id {
+					isExist = true
+					break
+				}
+			}
+
+			// weight(u, v)
+			weight, err := g.GetWeight(uID, vID)
+			if err != nil {
+				return nil, err
+			}
+
+			// if v ∈ Q and distance[v] > weight(u, v):
+			if isExist && distance[vID] > weight {
+
+				// distance[v] = weight(u, v)
+				distance[vID] = weight
+
+				// prev[v] = u
+				prev[vID] = uID
+
+				// Q.decrease_priority(v, weight(u, v))
+				minHeap.updateDistance(vID, weight)
+				heap.Init(minHeap)
+			}
+		}
+	}
+
+	tree := make(map[Edge]struct{})
+	for k, v := range prev {
+		weight, err := g.GetWeight(v, k)
+		if err != nil {
+			return nil, err
+		}
+		tree[NewEdge(g.GetNode(v), g.GetNode(k), weight)] = struct{}{}
+	}
+	return tree, nil
+}
+
+type nodeDistance struct {
+	id       ID
+	distance float64
+}
+
+// container.Heap's Interface needs sort.Interface, Push, Pop to be implemented
+
+// nodeDistanceHeap is a min-heap of nodeDistances.
+type nodeDistanceHeap []nodeDistance
+
+func (h nodeDistanceHeap) Len() int           { return len(h) }
+func (h nodeDistanceHeap) Less(i, j int) bool { return h[i].distance < h[j].distance } // Min-Heap
+func (h nodeDistanceHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
+
+func (h *nodeDistanceHeap) Push(x interface{}) {
+	*h = append(*h, x.(nodeDistance))
+}
+
+func (h *nodeDistanceHeap) Pop() interface{} {
+	heapSize := len(*h)
+	lastNode := (*h)[heapSize-1]
+	*h = (*h)[0 : heapSize-1]
+	return lastNode
+}
+
+func (h *nodeDistanceHeap) updateDistance(id ID, val float64) {
+	for i := 0; i < len(*h); i++ {
+		if (*h)[i].id == id {
+			(*h)[i].distance = val
+			break
+		}
+	}
+}
diff --git a/vendor/github.com/gyuho/goraph/shortest_path.go b/vendor/github.com/gyuho/goraph/shortest_path.go
new file mode 100644
index 0000000..e6f405c
--- /dev/null
+++ b/vendor/github.com/gyuho/goraph/shortest_path.go
@@ -0,0 +1,348 @@
+package goraph
+
+import (
+	"container/heap"
+	"fmt"
+	"math"
+)
+
+// Dijkstra returns the shortest path using Dijkstra
+// algorithm with a min-priority queue. This algorithm
+// does not work with negative weight edges.
+// (https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)
+//
+//	 0. Dijkstra(G, source, target)
+//	 1.
+//	 2. 	let Q be a priority queue
+//	 3. 	distance[source] = 0
+//	 4.
+//	 5. 	for each vertex v in G:
+//	 6.
+//	 7. 		if v ≠ source:
+//	 8. 			distance[v] = ∞
+//	 9. 			prev[v] = undefined
+//	10.
+//	11. 		Q.add_with_priority(v, distance[v])
+//	12.
+//	13. 	while Q is not empty:
+//	14.
+//	15. 		u = Q.extract_min()
+//	16. 		if u == target:
+//	17. 			break
+//	18.
+//	19. 		for each child vertex v of u:
+//	20.
+//	21. 			alt = distance[u] + weight(u, v)
+//	22. 			if distance[v] > alt:
+//	23. 				distance[v] = alt
+//	24. 				prev[v] = u
+//	25. 				Q.decrease_priority(v, alt)
+//	26.
+//	27. 		reheapify(Q)
+//	28.
+//	29.
+//	30. 	path = []
+//	31. 	u = target
+//	32. 	while prev[u] is defined:
+//	33. 		path.push_front(u)
+//	34. 		u = prev[u]
+//	35.
+//	36. 	return path, prev
+//
+func Dijkstra(g Graph, source, target ID) ([]ID, map[ID]float64, error) {
+	// let Q be a priority queue
+	minHeap := &nodeDistanceHeap{}
+
+	// distance[source] = 0
+	distance := make(map[ID]float64)
+	distance[source] = 0.0
+
+	// for each vertex v in G:
+	for id := range g.GetNodes() {
+		// if v ≠ source:
+		if id != source {
+			// distance[v] = ∞
+			distance[id] = math.MaxFloat64
+
+			// prev[v] = undefined
+			// prev[v] = ""
+		}
+
+		// Q.add_with_priority(v, distance[v])
+		nds := nodeDistance{}
+		nds.id = id
+		nds.distance = distance[id]
+
+		heap.Push(minHeap, nds)
+	}
+
+	heap.Init(minHeap)
+	prev := make(map[ID]ID)
+
+	// while Q is not empty:
+	for minHeap.Len() != 0 {
+
+		// u = Q.extract_min()
+		u := heap.Pop(minHeap).(nodeDistance)
+
+		// if u == target:
+		if u.id == target {
+			break
+		}
+
+		// for each child vertex v of u:
+		cmap, err := g.GetTargets(u.id)
+		if err != nil {
+			return nil, nil, err
+		}
+		for v := range cmap {
+
+			// alt = distance[u] + weight(u, v)
+			weight, err := g.GetWeight(u.id, v)
+			if err != nil {
+				return nil, nil, err
+			}
+			alt := distance[u.id] + weight
+
+			// if distance[v] > alt:
+			if distance[v] > alt {
+
+				// distance[v] = alt
+				distance[v] = alt
+
+				// prev[v] = u
+				prev[v] = u.id
+
+				// Q.decrease_priority(v, alt)
+				minHeap.updateDistance(v, alt)
+			}
+		}
+		heap.Init(minHeap)
+	}
+
+	// path = []
+	path := []ID{}
+
+	// u = target
+	u := target
+
+	// while prev[u] is defined:
+	for {
+		if _, ok := prev[u]; !ok {
+			break
+		}
+		// path.push_front(u)
+		temp := make([]ID, len(path)+1)
+		temp[0] = u
+		copy(temp[1:], path)
+		path = temp
+
+		// u = prev[u]
+		u = prev[u]
+	}
+
+	// add the source
+	temp := make([]ID, len(path)+1)
+	temp[0] = source
+	copy(temp[1:], path)
+	path = temp
+
+	return path, distance, nil
+}
+
+// BellmanFord returns the shortest path using Bellman-Ford algorithm
+// This algorithm works with negative weight edges.
+// Time complexity is O(|V||E|).
+// (http://courses.csail.mit.edu/6.006/spring11/lectures/lec15.pdf)
+// It returns error when there is a negative-weight cycle.
+// A negatively-weighted cycle adds up to infinite negative-weight.
+//
+//	 0. BellmanFord(G, source, target)
+//	 1.
+//	 2. 	distance[source] = 0
+//	 3.
+//	 4. 	for each vertex v in G:
+//	 5.
+//	 6. 		if v ≠ source:
+//	 7. 			distance[v] = ∞
+//	 8. 			prev[v] = undefined
+//	 9.
+//	10.
+//	11. 	for 1 to |V|-1:
+//	12.
+//	13. 		for every edge (u, v):
+//	14.
+//	15. 			alt = distance[u] + weight(u, v)
+//	16. 			if distance[v] > alt:
+//	17. 				distance[v] = alt
+//	18. 				prev[v] = u
+//	19.
+//	20.
+//	21. 	for every edge (u, v):
+//	22.
+//	23. 		alt = distance[u] + weight(u, v)
+//	24. 		if distance[v] > alt:
+//	25. 			there is a negative-weight cycle
+//	26.
+//	27.
+//	28. 	path = []
+//	29. 	u = target
+//	30. 	while prev[u] is defined:
+//	31. 		path.push_front(u)
+//	32. 		u = prev[u]
+//	33.
+//	34. 	return path, prev
+//
+func BellmanFord(g Graph, source, target ID) ([]ID, map[ID]float64, error) {
+	// distance[source] = 0
+	distance := make(map[ID]float64)
+	distance[source] = 0.0
+
+	// for each vertex v in G:
+	for id := range g.GetNodes() {
+
+		// if v ≠ source:
+		if id != source {
+			// distance[v] = ∞
+			distance[id] = math.MaxFloat64
+
+			// prev[v] = undefined
+			// prev[v] = ""
+		}
+	}
+
+	prev := make(map[ID]ID)
+
+	// for 1 to |V|-1:
+	for i := 1; i <= g.GetNodeCount()-1; i++ {
+
+		// for every edge (u, v):
+		for id := range g.GetNodes() {
+
+			cmap, err := g.GetTargets(id)
+			if err != nil {
+				return nil, nil, err
+			}
+			u := id
+			for v := range cmap {
+				// edge (u, v)
+				weight, err := g.GetWeight(u, v)
+				if err != nil {
+					return nil, nil, err
+				}
+
+				// alt = distance[u] + weight(u, v)
+				alt := distance[u] + weight
+
+				// if distance[v] > alt:
+				if distance[v] > alt {
+					// distance[v] = alt
+					distance[v] = alt
+
+					// prev[v] = u
+					prev[v] = u
+				}
+			}
+
+			pmap, err := g.GetSources(id)
+			if err != nil {
+				return nil, nil, err
+			}
+			v := id
+			for u := range pmap {
+				// edge (u, v)
+				weight, err := g.GetWeight(u, v)
+				if err != nil {
+					return nil, nil, err
+				}
+
+				// alt = distance[u] + weight(u, v)
+				alt := distance[u] + weight
+
+				// if distance[v] > alt:
+				if distance[v] > alt {
+					// distance[v] = alt
+					distance[v] = alt
+
+					// prev[v] = u
+					prev[v] = u
+				}
+			}
+		}
+	}
+
+	// for every edge (u, v):
+	for id := range g.GetNodes() {
+
+		cmap, err := g.GetTargets(id)
+		if err != nil {
+			return nil, nil, err
+		}
+		u := id
+		for v := range cmap {
+			// edge (u, v)
+			weight, err := g.GetWeight(u, v)
+			if err != nil {
+				return nil, nil, err
+			}
+
+			// alt = distance[u] + weight(u, v)
+			alt := distance[u] + weight
+
+			// if distance[v] > alt:
+			if distance[v] > alt {
+				return nil, nil, fmt.Errorf("there is a negative-weight cycle: %v", g)
+			}
+		}
+
+		pmap, err := g.GetSources(id)
+		if err != nil {
+			return nil, nil, err
+		}
+		v := id
+		for u := range pmap {
+			// edge (u, v)
+			weight, err := g.GetWeight(u, v)
+			if err != nil {
+				return nil, nil, err
+			}
+
+			// alt = distance[u] + weight(u, v)
+			alt := distance[u] + weight
+
+			// if distance[v] > alt:
+			if distance[v] > alt {
+				return nil, nil, fmt.Errorf("there is a negative-weight cycle: %v", g)
+			}
+		}
+	}
+
+	// path = []
+	path := []ID{}
+
+	// u = target
+	u := target
+
+	// while prev[u] is defined:
+	for {
+		if _, ok := prev[u]; !ok {
+			break
+		}
+		// path.push_front(u)
+		temp := make([]ID, len(path)+1)
+		temp[0] = u
+		copy(temp[1:], path)
+		path = temp
+
+		// u = prev[u]
+		u = prev[u]
+	}
+
+	// add the source
+	temp := make([]ID, len(path)+1)
+	temp[0] = source
+	copy(temp[1:], path)
+	path = temp
+
+	return path, distance, nil
+}
diff --git a/vendor/github.com/gyuho/goraph/strongly_connected_components.go b/vendor/github.com/gyuho/goraph/strongly_connected_components.go
new file mode 100644
index 0000000..b0a11a5
--- /dev/null
+++ b/vendor/github.com/gyuho/goraph/strongly_connected_components.go
@@ -0,0 +1,195 @@
+package goraph
+
+import "sync"
+
+// Tarjan finds the strongly connected components.
+// In the mathematics, a directed graph is "strongly connected"
+// if every vertex is reachable from every other node.
+// Therefore, a graph is strongly connected if there is a path
+// in each direction between each pair of node of a graph.
+// Then a pair of vertices u and v is strongly connected to each other
+// because there is a path in each direction.
+// "Strongly connected components" of an arbitrary graph
+// partition into sub-graphs that are themselves strongly connected.
+// That is, "strongly connected component" of a directed graph
+// is a sub-graph that is strongly connected.
+// Formally, "Strongly connected components" of a graph is a maximal
+// set of vertices C in G.V such that for all u, v ∈ C, there is a path
+// both from u to v, and from v to u.
+// (https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm)
+//
+//	 0. Tarjan(G):
+//	 1.
+//	 2. 	globalIndex = 0 // smallest unused index
+//	 3. 	let S be a stack
+//	 4. 	result = [][]
+//	 5.
+//	 6. 	for each vertex v in G:
+//	 7. 		if v.index is undefined:
+//	 8. 			tarjan(G, v, globalIndex, S, result)
+//	 9.
+//	10. 	return result
+//	11.
+//	12.
+//	13. tarjan(G, v, globalIndex, S, result):
+//	14.
+//	15. 	v.index = globalIndex
+//	16. 	v.lowLink = globalIndex
+//	17. 	globalIndex++
+//	18. 	S.push(v)
+//	19.
+//	20. 	for each child vertex w of v:
+//	21.
+//	22. 		if w.index is undefined:
+//	23. 			recursively tarjan(G, w, globalIndex, S, result)
+//	24. 			v.lowLink = min(v.lowLink, w.lowLink)
+//	25.
+//	26. 		else if w is in S:
+//	27. 			v.lowLink = min(v.lowLink, w.index)
+//	28.
+//	29. 	// if v is the root
+//	30. 	if v.lowLink == v.index:
+//	31.
+//	32. 		// start a new strongly connected component
+//	33. 		component = []
+//	34.
+//	35. 		while True:
+//	36.
+//	37. 			u = S.pop()
+//	38. 			component.push(u)
+//	39.
+//	40. 			if u == v:
+//	41. 				result.push(component)
+//	42. 				break
+//
+func Tarjan(g Graph) [][]ID {
+	d := newTarjanData()
+
+	// for each vertex v in G:
+	for v := range g.GetNodes() {
+		// if v.index is undefined:
+		if _, ok := d.index[v]; !ok {
+			// tarjan(G, v, globalIndex, S, result)
+			tarjan(g, v, d)
+		}
+	}
+	return d.result
+}
+
+type tarjanData struct {
+	mu sync.Mutex // guards the following
+
+	// globalIndex is the smallest unused index
+	globalIndex int
+
+	// index is an index of a node to record
+	// the order of being discovered.
+	index map[ID]int
+
+	// lowLink is the smallest index of any index
+	// reachable from v, including v itself.
+	lowLink map[ID]int
+
+	// S is the stack.
+	S []ID
+
+	// extra map to check if a vertex is in S.
+	smap map[ID]struct{}
+
+	result [][]ID
+}
+
+func newTarjanData() *tarjanData {
+	return &tarjanData{
+		globalIndex: 0,
+		index:       make(map[ID]int),
+		lowLink:     make(map[ID]int),
+		S:           []ID{},
+		smap:        make(map[ID]struct{}),
+		result:      [][]ID{},
+	}
+}
+
+func tarjan(
+	g Graph,
+	id ID,
+	data *tarjanData,
+) {
+	// This is not inherently parallelizable problem,
+	// but just to make sure.
+	data.mu.Lock()
+
+	// v.index = globalIndex
+	data.index[id] = data.globalIndex
+
+	// v.lowLink = globalIndex
+	data.lowLink[id] = data.globalIndex
+
+	// globalIndex++
+	data.globalIndex++
+
+	// S.push(v)
+	data.S = append(data.S, id)
+	data.smap[id] = struct{}{}
+
+	data.mu.Unlock()
+
+	// for each child vertex w of v:
+	cmap, err := g.GetTargets(id)
+	if err != nil {
+		panic(err)
+	}
+	for w := range cmap {
+
+		// if w.index is undefined:
+		if _, ok := data.index[w]; !ok {
+
+			// recursively tarjan(G, w, globalIndex, S, result)
+			tarjan(g, w, data)
+
+			// v.lowLink = min(v.lowLink, w.lowLink)
+			data.lowLink[id] = min(data.lowLink[id], data.lowLink[w])
+
+		} else if _, ok := data.smap[w]; ok {
+			// else if w is in S:
+
+			// v.lowLink = min(v.lowLink, w.index)
+			data.lowLink[id] = min(data.lowLink[id], data.index[w])
+		}
+	}
+
+	data.mu.Lock()
+	defer data.mu.Unlock()
+
+	// if v is the root
+	// if v.lowLink == v.index:
+	if data.lowLink[id] == data.index[id] {
+		// start a new strongly connected component
+		component := []ID{}
+
+		// while True:
+		for {
+
+			// u = S.pop()
+			u := data.S[len(data.S)-1]
+			data.S = data.S[:len(data.S)-1 : len(data.S)-1]
+			delete(data.smap, u)
+
+			// component.push(u)
+			component = append(component, u)
+
+			// if u == v:
+			if u == id {
+				data.result = append(data.result, component)
+				break
+			}
+		}
+	}
+}
+
+func min(a, b int) int {
+	if a < b {
+		return a
+	}
+	return b
+}
diff --git a/vendor/github.com/gyuho/goraph/test b/vendor/github.com/gyuho/goraph/test
new file mode 100755
index 0000000..a7d8a6d
--- /dev/null
+++ b/vendor/github.com/gyuho/goraph/test
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+TEST=./...;
+FMT="*.go"
+
+echo "Running tests...";
+go test -v -cover -cpu 1,2,4 $TEST;
+go test -v -cover -cpu 1,2,4 -race $TEST;
+
+echo "Checking gofmt..."
+fmtRes=$(gofmt -l -s $FMT)
+if [ -n "${fmtRes}" ]; then
+	echo -e "gofmt checking failed:\n${fmtRes}"
+	exit 255
+fi
+
+echo "Checking govet..."
+vetRes=$(go vet $TEST)
+if [ -n "${vetRes}" ]; then
+	echo -e "govet checking failed:\n${vetRes}"
+	exit 255
+fi
+
+echo "Success";
diff --git a/vendor/github.com/gyuho/goraph/topological_sort.go b/vendor/github.com/gyuho/goraph/topological_sort.go
new file mode 100644
index 0000000..b63675a
--- /dev/null
+++ b/vendor/github.com/gyuho/goraph/topological_sort.go
@@ -0,0 +1,98 @@
+package goraph
+
+// TopologicalSort does topological sort(ordering) with DFS.
+// It returns true if the graph is a DAG (no cycle, with a topological sort).
+// False if the graph is not a DAG (cycle, with no topological sort).
+//
+//	 0. TopologicalSort(G)
+//	 1.
+//	 2. 	L = Empty list that will contain the sorted nodes
+//	 3. 	isDAG = true
+//	 4.
+//	 5. 	for each vertex v in G:
+//	 6.
+//	 7. 		if v.color == "white":
+//	 8.
+//	 9. 			topologicalSortVisit(v, L, isDAG)
+//	10.
+//	11.
+//	12.
+//	13.
+//	14. topologicalSortVisit(v, L, isDAG)
+//	15.
+//	16. 	if v.color == "gray":
+//	17. 		isDAG = false
+//	18. 		return
+//	19.
+//	20. 	if v.color == "white":
+//	21.
+//	22. 		v.color = "gray":
+//	23.
+//	24.			for each child vertex w of v:
+//	25. 			topologicalSortVisit(w, L, isDAG)
+//	26.
+//	27. 		v.color = "black"
+//	28.			L.push_front(v)
+//
+func TopologicalSort(g Graph) ([]ID, bool) {
+
+	// L = Empty list that will contain the sorted nodes
+	L := []ID{}
+	isDAG := true
+	color := make(map[ID]string)
+	for v := range g.GetNodes() {
+		color[v] = "white"
+	}
+
+	// for each vertex v in G:
+	for v := range g.GetNodes() {
+		// if v.color == "white":
+		if color[v] == "white" {
+			// topologicalSortVisit(v, L, isDAG)
+			topologicalSortVisit(g, v, &L, &isDAG, &color)
+		}
+	}
+
+	return L, isDAG
+}
+
+func topologicalSortVisit(
+	g Graph,
+	id ID,
+	L *[]ID,
+	isDAG *bool,
+	color *map[ID]string,
+) {
+
+	// if v.color == "gray":
+	if (*color)[id] == "gray" {
+		// isDAG = false
+		*isDAG = false
+		return
+	}
+
+	// if v.color == "white":
+	if (*color)[id] == "white" {
+		// v.color = "gray":
+		(*color)[id] = "gray"
+
+		// for each child vertex w of v:
+		cmap, err := g.GetTargets(id)
+		if err != nil {
+			panic(err)
+		}
+		for w := range cmap {
+			// topologicalSortVisit(w, L, isDAG)
+			topologicalSortVisit(g, w, L, isDAG, color)
+		}
+
+		// v.color = "black"
+		(*color)[id] = "black"
+
+		// L.push_front(v)
+		temp := make([]ID, len(*L)+1)
+		temp[0] = id
+		copy(temp[1:], *L)
+		*L = temp
+	}
+}
diff --git a/vendor/github.com/gyuho/goraph/traversal.go b/vendor/github.com/gyuho/goraph/traversal.go
new file mode 100644
index 0000000..fa45c29
--- /dev/null
+++ b/vendor/github.com/gyuho/goraph/traversal.go
@@ -0,0 +1,184 @@
+package goraph
+
+// BFS does breadth-first search, and returns the list of vertices.
+// (https://en.wikipedia.org/wiki/Breadth-first_search)
+//
+//	 0. BFS(G, v):
+//	 1.
+//	 2. 	let Q be a queue
+//	 3. 	Q.push(v)
+//	 4. 	label v as visited
+//	 5.
+//	 6. 	while Q is not empty:
+//	 7.
+//	 8. 		u = Q.dequeue()
+//	 9.
+//	10. 		for each vertex w adjacent to u:
+//	11.
+//	12. 			if w is not visited yet:
+//	13. 				Q.push(w)
+//	14. 				label w as visited
+//
+func BFS(g Graph, id ID) []ID {
+	if g.GetNode(id) == nil {
+		return nil
+	}
+
+	q := []ID{id}
+	visited := make(map[ID]bool)
+	visited[id] = true
+	rs := []ID{id}
+
+	// while Q is not empty:
+	for len(q) != 0 {
+
+		u := q[0]
+		q = q[1:len(q):len(q)]
+
+		// for each vertex w adjacent to u:
+		cmap, _ := g.GetTargets(u)
+		for _, w := range cmap {
+			// if w is not visited yet:
+			if _, ok := visited[w.ID()]; !ok {
+				q = append(q, w.ID())  // Q.push(w)
+				visited[w.ID()] = true // label w as visited
+
+				rs = append(rs, w)
+			}
+		}
+		pmap, _ := g.GetSources(u)
+		for _, w := range pmap {
+			// if w is not visited yet:
+			if _, ok := visited[w.ID()]; !ok {
+				q = append(q, w.ID())  // Q.push(w)
+				visited[w.ID()] = true // label w as visited
+
+				rs = append(rs, w.ID())
+			}
+		}
+	}
+
+	return rs
+}
+
+// DFS does depth-first search, and returns the list of vertices.
+// (https://en.wikipedia.org/wiki/Depth-first_search)
+//
+//	 0. DFS(G, v):
+//	 1.
+//	 2. 	let S be a stack
+//	 3. 	S.push(v)
+//	 4.
+//	 5. 	while S is not empty:
+//	 6.
+//	 7. 		u = S.pop()
+//	 8.
+//	 9. 		if u is not visited yet:
+//	10.
+//	11. 			label u as visited
+//	12.
+//	13. 			for each vertex w adjacent to u:
+//	14.
+//	15. 				if w is not visited yet:
+//	16. 					S.push(w)
+//
+func DFS(g Graph, id ID) []ID {
+	if g.GetNode(id) == nil {
+		return nil
+	}
+
+	s := []ID{id}
+	visited := make(map[ID]bool)
+	rs := []ID{}
+
+	// while S is not empty:
+	for len(s) != 0 {
+
+		u := s[len(s)-1]
+		s = s[:len(s)-1 : len(s)-1]
+
+		// if u is not visited yet:
+		if _, ok := visited[u]; !ok {
+			// label u as visited
+			visited[u] = true
+
+			rs = append(rs, u)
+
+			// for each vertex w adjacent to u:
+			cmap, _ := g.GetTargets(u)
+			for _, w := range cmap {
+				// if w is not visited yet:
+				if _, ok := visited[w.ID()]; !ok {
+					s = append(s, w.ID()) // S.push(w)
+				}
+			}
+			pmap, _ := g.GetSources(u)
+			for _, w := range pmap {
+				// if w is not visited yet:
+				if _, ok := visited[w.ID()]; !ok {
+					s = append(s, w.ID()) // S.push(w)
+				}
+			}
+		}
+	}
+
+	return rs
+}
+
+// DFSRecursion does depth-first search recursively.
+//
+//	 0. DFS(G, v):
+//	 1.
+//	 2. 	if v is visited:
+//	 3. 		return
+//	 4.
+//	 5. 	label v as visited
+//	 6.
+//	 7. 	for each vertex u adjacent to v:
+//	 8.
+//	 9. 		if u is not visited yet:
+//	10. 			recursive DFS(G, u)
+//
+func DFSRecursion(g Graph, id ID) []ID {
+	if g.GetNode(id) == nil {
+		return nil
+	}
+
+	visited := make(map[ID]bool)
+	rs := []ID{}
+
+	dfsRecursion(g, id, visited, &rs)
+
+	return rs
+}
+
+func dfsRecursion(g Graph, id ID, visited map[ID]bool, rs *[]ID) {
+	// base case of recursion
+	//
+	// if v is visited:
+	if _, ok := visited[id]; ok {
+		return
+	}
+
+	// label v as visited
+	visited[id] = true
+	*rs = append(*rs, id)
+
+	// for each vertex u adjacent to v:
+	cmap, _ := g.GetTargets(id)
+	for _, u := range cmap {
+		// if u is not visited yet:
+		if _, ok := visited[u.ID()]; !ok {
+			// recursive DFS(G, u)
+			dfsRecursion(g, u.ID(), visited, rs)
+		}
+	}
+	pmap, _ := g.GetSources(id)
+	for _, u := range pmap {
+		// if u is not visited yet:
+		if _, ok := visited[u.ID()]; !ok {
+			// recursive DFS(G, u)
+			dfsRecursion(g, u.ID(), visited, rs)
+		}
+	}
+}
