-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdfs.go
96 lines (82 loc) · 2.34 KB
/
dfs.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
package main
import (
"fmt"
"os"
)
// 记录一个边的信息,包括其 vertex_id, vertex_label, edge_label
type DFS struct {
from, to, fromlabel, elabel, tolabel int
}
/* 一个图的 DFSCode,DFSCode 相同等价于图同构
DFSCode 中包含了图的所有边
*/
type DFSCode []DFS
func (dc *DFSCode) push(from, to, fromlabel, elabel, tolabel int) {
*dc = append(*dc, DFS{from, to, fromlabel, elabel, tolabel})
}
func (dc *DFSCode) pop() {
if len(*dc) > 0 {
*dc = (*dc)[:len(*dc)-1]
}
}
// 从一个图中构建 DFSCode,注意需要保证图 g 连通
func (dc *DFSCode) fromGraph(g *Graph) {
*dc = make(DFSCode, 0)
for from, v := range g.VertexArray {
// 找到在所有 v 的临边中,相连的节点 nei.label 比 v.label 大的边,目的是对无向图中的双连接去重
edgeList := g.getForwardRoot(&v)
for _, e := range edgeList {
assert(e.from == from)
dc.push(from, e.to, g.VertexArray[e.from].label, e.elabel, g.VertexArray[e.to].label)
}
}
}
// 将 DFSCode 转化为一个图
func (dc *DFSCode) toGraph(g *Graph) {
g.VertexArray = make(VertexArray, dc.nodeCount())
for _, dfs := range *dc {
if dfs.fromlabel != -1 {
g.VertexArray[dfs.from].label = dfs.fromlabel
}
if dfs.tolabel != -1 {
g.VertexArray[dfs.to].label = dfs.tolabel
}
g.VertexArray[dfs.from].push(dfs.from, dfs.to, dfs.elabel)
g.VertexArray[dfs.to].push(dfs.to, dfs.from, dfs.elabel)
}
g.buildEdge()
}
// 获得 DFSCode 所代表的图中的节点数
func (dc *DFSCode) nodeCount() int {
nodeCount := 0
for i := 0; i < len(*dc); i++ {
nodeCount = maxint(nodeCount, maxint((*dc)[i].from, (*dc)[i].to)+1)
}
return nodeCount
}
// 打印 DFSCode
func (dc DFSCode) write(fout *os.File) {
if len(dc) == 0 {
return
}
fmt.Fprintf(fout, "(%d) %d (0f%d)", dc[0].fromlabel, dc[0].elabel, dc[0].tolabel)
for i := 1; i < len(dc); i++ {
if dc[i].from < dc[i].to {
fmt.Fprintf(fout, " %d (%df%d)", dc[i].elabel, dc[i].from, dc[i].tolabel)
} else {
fmt.Fprintf(fout, " %d (b%d)", dc[i].elabel, dc[i].to)
}
}
}
// 在 DFSCode 上获取最右路径
func (dc *DFSCode) buildRMPath() []int {
rmpath := make([]int, 0)
old_from := -1
for i := len(*dc) - 1; i >= 0; i-- {
if (*dc)[i].from < (*dc)[i].to && (len(rmpath) == 0 || old_from == (*dc)[i].to) {
rmpath = append(rmpath, i)
old_from = (*dc)[i].from
}
}
return rmpath
}