-
Notifications
You must be signed in to change notification settings - Fork 1
/
vcover.js
104 lines (93 loc) · 2.05 KB
/
vcover.js
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
"use strict"
var pool = require("typedarray-pool")
var iota = require("iota-array")
var bipartiteMatching = require("bipartite-matching")
module.exports = bipartiteVertexCover
function walk(list, v, adjL, matchL, coverL, matchR, coverR) {
if(coverL[v] || matchL[v] >= 0) {
return
}
while(v >= 0) {
coverL[v] = 1
var adj = adjL[v]
var next = -1
for(var i=0,l=adj.length; i<l; ++i) {
var u = adj[i]
if(coverR[u]) {
continue
}
next = u
}
if(next < 0) {
break
}
coverR[next] = 1
list.push(next)
v = matchR[next]
}
}
function bipartiteVertexCover(n, m, edges) {
var match = bipartiteMatching(n, m, edges)
//Initialize adjacency lists
var adjL = new Array(n)
var matchL = pool.mallocInt32(n)
var matchCount = pool.mallocInt32(n)
var coverL = pool.mallocInt32(n)
for(var i=0; i<n; ++i) {
adjL[i] = []
matchL[i] = -1
matchCount[i] = 0
coverL[i] = 0
}
var adjR = new Array(m)
var matchR = pool.mallocInt32(m)
var coverR = pool.mallocInt32(m)
for(var i=0; i<m; ++i) {
adjR[i] = []
matchR[i] = -1
coverR[i] = 0
}
//Unpack matching
for(var i=0,l=match.length; i<l; ++i) {
var s = match[i][0]
var t = match[i][1]
matchL[s] = t
matchR[t] = s
}
//Loop over edges
for(var i=0,l=edges.length; i<l; ++i) {
var e = edges[i]
var s = e[0]
var t = e[1]
if(matchL[s] === t) {
if(!(matchCount[s]++)) {
continue
}
}
adjL[s].push(t)
adjR[t].push(s)
}
//Construct cover
var left = []
var right = []
for(var i=0; i<n; ++i) {
walk(right, i, adjL, matchL, coverL, matchR, coverR)
}
for(var i=0; i<m; ++i) {
walk(left, i, adjR, matchR, coverR, matchL, coverL)
}
//Clean up any left over edges
for(var i=0; i<n; ++i) {
if(!coverL[i] && matchL[i] >= 0) {
coverR[matchL[i]] = coverL[i] = 1
left.push(i)
}
}
//Clean up data
pool.free(coverR)
pool.free(matchR)
pool.free(coverL)
pool.free(matchCount)
pool.free(matchL)
return [ left, right ]
}