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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
var minimumCost = function(source, target, original, changed, cost) { class Graph { constructor() { this.Nodelist = {} }
addNode(node) { if (!this.Nodelist[node]) this.Nodelist[node] = [] }
addEdge(node1, node2, weight) { this.Nodelist[node1].push({node: node2, weight}) }
checkNodeExist(node) { if (this.Nodelist[node]) { return true } else { return false } }
dijkstra(start, end) { if (!this.checkNodeExist(start) && !this.checkNodeExist(end)) return -1 const queue = new Queue() let smallest
for (let node in this.Nodelist) { if (node === start) { queue.enqueue(node, 0) } else { queue.enqueue(node, Infinity) } }
while (queue.values.length) { smallest = queue.dequeue()
if (smallest.val === end) { if (smallest.path === Infinity) { return -1 } return smallest.path } if (smallest.val) { for (let {node, weight} of this.Nodelist[smallest.val]) { queue.editPath(node, weight + smallest.path) } }
} } }
class Queue { constructor() { this.values = [] }
enqueue(val, path) { this.values.push({val, path}) }
dequeue() { if (this.values.length === 0) return null
let minValueObj = this.values.reduce((min, current) => { return current.path < min.path ? current : min }) let index = this.values.findIndex(item => item.path === minValueObj.path) if (index !== -1) { this.values.splice(index, 1) } return minValueObj }
editPath(node, path) { for (let i = 0; i < this.values.length; i++) { if (this.values[i].val === node) { this.values[i].path = Math.min(path, this.values[i].path) break } } } }
let graph = new Graph() for (let i = 0; i < original.length; i++) { graph.addNode(original[i]) graph.addNode(changed[i]) graph.addEdge(original[i], changed[i], cost[i]) } let totalCost = 0 let _cost for (let i = 0; i < source.length; i++) { let pathStr = source[i] + target[i] if (costMem.has(pathStr)) { _cost = costMem.get(pathStr) } else { _cost = graph.dijkstra(source[i], target[i]) costMem.set(pathStr, _cost) } if (_cost === -1) return -1 totalCost += _cost } return totalCost };
|