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 C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
    static void Main()
    {
        int n = int.Parse(Console.ReadLine());
        Tree t = new Tree(n);
        List<Edge> el = new List<Edge>();
        for (int i = 0; i < n; i++)
        {
            int[] e = Console.ReadLine().Substring(1).Split(' ').Select(s => int.Parse(s)).ToArray();
            for (int j = 0; j < n; j++)
                if (e[j] != -1)
                    el.Add(new Edge(i + 1, j + 1, e[j]));
        }
        IC ic = new IC();
        el.Sort(ic);
        int ans = 0;
        foreach (var ed in el)
        {
            if (!t.IsSameSet(ed.s, ed.g))
            {
                ans += ed.length;
                t.unite(ed.s, ed.g);
            }
        }
        Console.WriteLine(ans);
    }
}
class Tree
{
    private int[] p; //頂点iの親がp[i-1]
    public Tree(int n) //コンストラクタ
    {
        p = new int[n];
        for (int i = 0; i < n; i++) p[i] = i + 1;
    }
    public int GetParent(int a) //aの親を返す
    {
        return p[a - 1];
    }
    public void SetParent(int a, int b) //aの親をbに設定
    {
        p[a - 1] = b;
    }
    public int root(int a) //aのrootを求め、aの親にする
    {
        if (p[a - 1] == a) return a;
        return (p[a - 1] = root(p[a - 1]));
    }
    public bool IsSameSet(int a, int b) //aとbが同一グループに属するか
    {
        return root(a) == root(b);
    }
    public void unite(int a, int b) //aとbを同一グループにまとめる
    {
        p[root(a) - 1] = root(b);
    }
}
class IC : IComparer<Edge>
{
    public int Compare(Edge e1, Edge e2)
    {
        return e1.length - e2.length;
    }
}
class Edge
{
    public int s;
    public int g;
    public int length;
    public Edge(int s, int g, int length)
    {
        this.s = s;
        this.g = g;
        this.length = length;
    }
}