Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Minimum Spanning Tree

For a given weighted graph $G = (V, E)$, find the minimum spanning tree (MST) of $G$ and print total weight of edges belong to the MST.

Input

In the first line, an integer $n$ denoting the number of vertices in $G$ is given. In the following $n$ lines, a $n \times n$ adjacency matrix $A$ which represents $G$ is given.
$a_{ij}$ denotes the weight of edge connecting vertex $i$ and vertex $j$. If there is no edge between $i$ and $j$, $a_{ij}$ is given by -1.

Output

Print the total weight of the minimum spanning tree of $G$.

Constraints

$1 \leq n \leq 100$

$0 \leq a_{ij} \leq 2,000$ (if $a_{ij} \neq -1$)

$a_{ij} = a_{ji}$

$G$ is a connected graph

Sample Input 1

5
-1 2 3 1 -1
2 -1 -1 4 -1
3 -1 -1 1 1
1 4 1 -1 3
-1 -1 1 3 -1

Sample Output 1

5

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

Solution in Scala (judge verdict: Accepted)

import scala.io.StdIn.{readLine, readInt};
import scala.reflect.ClassTag;
object Main {
    def main(args: Array[String]): Unit = {
        val n = readInt;
        val graph = new Array[List[(Int, Int)]](n); // (cost, index)
        (0 until n).foreach { i =>
            graph(i) = readLine.trim.split(" ").map(_.toInt).zipWithIndex.filter(_._1 != -1).toList
        }
        println(mst(graph).sum);
    }
    
    def mst(graph: Array[List[(Int, Int)]]): Array[Int] = {
        val len = graph.length;
        val dist = new Array[Int](len).map( i => -1);
        implicit val ord = Ordering.by((e: (Int, Int)) => e._1).reverse;
        val pq = new PriorityQueue(10000);
        pq.enqueue((0, 0));
        def go(): Unit = {
            pq.dequeueOption match {
                case None => ();
                case Some((minCost, minIdx)) => {
                    if (dist(minIdx) == -1) {
                        dist(minIdx) = minCost;
                        graph(minIdx).foreach { e => pq.enqueue(e)}
                    }
                    go;
                }
            }
        }
        go;
        dist;
    }
}

class PriorityQueue[A](size: Int)(implicit m: ClassTag[A], ord: Ordering[A]) {
    import ord._;
    private[this] val pq = m.newArray(size);
    private[this] var ptr = 0;
    
    def enqueue(e: A): Unit = {
        def go(curr: Int): Unit = {
            val parent = if (curr % 2 == 1) (curr - 1) / 2 else (curr - 2) / 2;
            if (parent >= 0 && pq(curr) > pq (parent)) {
                swap(curr, parent);
                go(parent);
            }
        }
        pq(ptr) = e;
        go(ptr);
        ptr += 1;
    }
    def dequeue(): A = {
        if (ptr == 0) {
            throw new NoSuchElementException("value is not found");
        } else if (ptr == 1) {
            ptr = 0;
            pq(0);
        } else {
            ptr -= 1;
            val ret = pq(0);
            pq(0) = pq(ptr);
            heapify(0);
            ret;
        }
    }
    
    def dequeueOption(): Option[A] = {
        try {
            Option(dequeue());
        } catch {
            case e: Exception => None;
        }
    }
    
    private def heapify(curr: Int): Unit = {
        val left = curr * 2 + 1;
        val right = curr * 2 + 2;
        if (right < ptr) {
            val maxIdx = max(curr, left, right);
            if (curr != maxIdx) {
                swap(curr, maxIdx);
                heapify(maxIdx);
            }
        } else if (left < ptr) {
            if (pq(left) > pq(curr)) swap(curr, left);
        }
    }
    
    private def max(a: Int, b: Int, c: Int): Int = {
        if (pq(a) > pq(b)) {
            if (pq(a) > pq(c)) a else c;
        } else {
            if (pq(b) > pq(c)) b else c;
        }
    }
    
    private def swap(a: Int, b: Int): Unit = {
        val tmp = pq(a);
        pq(a) = pq(b);
        pq(b) = tmp;
    }
}