87 lines
2.0 KiB
JavaScript
87 lines
2.0 KiB
JavaScript
import _ from 'lodash'
|
|
|
|
function parentDummyChains (g) {
|
|
const postorderNums = postorder(g)
|
|
|
|
_.forEach(g.graph().dummyChains, function (v) {
|
|
let node = g.node(v)
|
|
const edgeObj = node.edgeObj
|
|
const pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w)
|
|
const path = pathData.path
|
|
const lca = pathData.lca
|
|
let pathIdx = 0
|
|
let pathV = path[pathIdx]
|
|
let ascending = true
|
|
|
|
while (v !== edgeObj.w) {
|
|
node = g.node(v)
|
|
|
|
if (ascending) {
|
|
while ((pathV = path[pathIdx]) !== lca &&
|
|
g.node(pathV).maxRank < node.rank) {
|
|
pathIdx++
|
|
}
|
|
|
|
if (pathV === lca) {
|
|
ascending = false
|
|
}
|
|
}
|
|
|
|
if (!ascending) {
|
|
while (pathIdx < path.length - 1 &&
|
|
g.node(pathV = path[pathIdx + 1]).minRank <= node.rank) {
|
|
pathIdx++
|
|
}
|
|
pathV = path[pathIdx]
|
|
}
|
|
|
|
g.setParent(v, pathV)
|
|
v = g.successors(v)[0]
|
|
}
|
|
})
|
|
}
|
|
|
|
// Find a path from v to w through the lowest common ancestor (LCA). Return the
|
|
// full path and the LCA.
|
|
function findPath (g, postorderNums, v, w) {
|
|
const vPath = []
|
|
const wPath = []
|
|
const low = Math.min(postorderNums[v].low, postorderNums[w].low)
|
|
const lim = Math.max(postorderNums[v].lim, postorderNums[w].lim)
|
|
let parent
|
|
let lca
|
|
|
|
// Traverse up from v to find the LCA
|
|
parent = v
|
|
do {
|
|
parent = g.parent(parent)
|
|
vPath.push(parent)
|
|
} while (parent &&
|
|
(postorderNums[parent].low > low || lim > postorderNums[parent].lim))
|
|
lca = parent
|
|
|
|
// Traverse from w to LCA
|
|
parent = w
|
|
while ((parent = g.parent(parent)) !== lca) {
|
|
wPath.push(parent)
|
|
}
|
|
|
|
return { path: vPath.concat(wPath.reverse()), lca: lca }
|
|
}
|
|
|
|
function postorder (g) {
|
|
const result = {}
|
|
let lim = 0
|
|
|
|
function dfs (v) {
|
|
const low = lim
|
|
_.forEach(g.children(v), dfs)
|
|
result[v] = { low: low, lim: lim++ }
|
|
}
|
|
_.forEach(g.children(), dfs)
|
|
|
|
return result
|
|
}
|
|
|
|
export default parentDummyChains
|