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.collection.mutable.ArrayBuffer

object Main {

  def main(args: Array[String]): Unit = {

    class UnionSet(par: Array[Int]) {
      def root(x: Int): Int =
        if (par(x) == x) x
        else {
          par(x) = root(par(x))
          par(x)
        }
      def unite(x: Int, y: Int): Unit = {
        val rx = root(x)
        val ry = root(y)
        if (rx != ry)
          par(rx) = ry
      }
      def same(x: Int, y: Int): Boolean =
        root(x) == root(y)
    }
    object UnionSet {
      def apply(n: Int): UnionSet =
        new UnionSet(Array.range(0, n))
    }

    val sc = new java.util.Scanner(System.in)

    val N = sc.nextInt()
    val W = Array.fill(N, N)(sc.nextInt())

    val _E = new ArrayBuffer[(Int, Int)]() // (辺(u,v), 重みw)
    (0 until N) foreach { i =>
      (0 until N) foreach { j =>
        if (W(i)(j) >= 0) {
          _E.append((i, j))
        }
      }
    }
    val E: List[(Int, Int)] = _E.sortBy(e => W(e._1)(e._2)).toList // 辺(軽い順)

    // 最初, 全ての頂点は別の木として初期化する
    val unionset = UnionSet(N)
    var count = 0
    // 軽い辺から見ていき
    E foreach { e =>
      val (u, v) = e
      // u, v が別の木ならば, これは軽い辺なので安全に追加できる.
      if (!unionset.same(u, v)) {
        unionset.unite(u, v)
        count += W(u)(v)
      }
    }

    // 入力が連結グラフであることから,最終的に出来上がった木は1本となり, これが最小全域木である
    // 加えた辺の重さの合計が最小全域木の重さの合計
    println(count)
  }

}