101 lines
2.4 KiB
TypeScript
101 lines
2.4 KiB
TypeScript
export {};
|
|
|
|
class PriorityQueue {
|
|
private heap: [number, number][] = [];
|
|
|
|
push(item: [number, number]): void {
|
|
this.heap.push(item);
|
|
this._bubbleUp();
|
|
}
|
|
|
|
pop(): [number, number] | undefined {
|
|
if (this.heap.length === 0) return undefined;
|
|
if (this.heap.length === 1) return this.heap.pop();
|
|
const root = this.heap[0];
|
|
this.heap[0] = this.heap.pop()!;
|
|
this._bubbleDown();
|
|
return root;
|
|
}
|
|
|
|
size(): number {
|
|
return this.heap.length;
|
|
}
|
|
|
|
isEmpty(): boolean {
|
|
return this.heap.length === 0;
|
|
}
|
|
|
|
private _bubbleUp(): void {
|
|
let index = this.heap.length - 1;
|
|
while (index > 0) {
|
|
const parentIdx = Math.floor((index - 1) / 2);
|
|
if (this.heap[index][0] >= this.heap[parentIdx][0]) break;
|
|
[this.heap[index], this.heap[parentIdx]] = [this.heap[parentIdx], this.heap[index]];
|
|
index = parentIdx;
|
|
}
|
|
}
|
|
|
|
private _bubbleDown(): void {
|
|
let index = 0;
|
|
const length = this.heap.length;
|
|
|
|
while (true) {
|
|
let smallestIdx = index;
|
|
const leftIdx = 2 * index + 1;
|
|
const rightIdx = 2 * index + 2;
|
|
|
|
if (leftIdx < length && this.heap[leftIdx][0] < this.heap[smallestIdx][0]) {
|
|
smallestIdx = leftIdx;
|
|
}
|
|
|
|
if (rightIdx < length && this.heap[rightIdx][0] < this.heap[smallestIdx][0]) {
|
|
smallestIdx = rightIdx;
|
|
}
|
|
|
|
if (smallestIdx === index) break;
|
|
|
|
[this.heap[index], this.heap[smallestIdx]] = [this.heap[smallestIdx], this.heap[index]];
|
|
index = smallestIdx;
|
|
}
|
|
}
|
|
}
|
|
|
|
const input = require("fs").readFileSync(0).toString().trim().split("\n");
|
|
const [V, E]: number[] = input[0].split(" ").map(Number);
|
|
|
|
let graph: number[][][] = Array.from({length: V+1}, () => []);
|
|
for(let i=1; i<=E; i++) {
|
|
let [u,v,w]: number[] = input[i].split(" ").map(Number);
|
|
graph[u].push([w,v]);
|
|
graph[v].push([w,u]);
|
|
}
|
|
|
|
const prim = (): number => {
|
|
let visited: boolean[] = new Array(V+1).fill(false);
|
|
let pq = new PriorityQueue();
|
|
pq.push([0,1]);
|
|
|
|
let total_weight: number = 0;
|
|
let count: number = 0;
|
|
|
|
while(pq.size() !== 0) {
|
|
let [w, v]: number[] = pq.pop();
|
|
|
|
if(visited[v]) continue;
|
|
|
|
visited[v] = true;
|
|
total_weight += w;
|
|
count++;
|
|
|
|
if(count === V) break;
|
|
|
|
for(let next of graph[v]) {
|
|
let [nw, nv] = next;
|
|
if(!visited[nv]) pq.push([nw, nv]);
|
|
}
|
|
}
|
|
|
|
return total_weight;
|
|
}
|
|
|
|
console.log(prim()); |