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;
					
public class Program
{
	static int[] parent;
	static int[] rank;
	
	public static void Main()
	{
		int n = int.Parse(Console.ReadLine());
		int[,] A = new int[n,n];
		
		for(int i = 0; i < n; i++) {
			var cells = Console.ReadLine().Trim(" ".ToCharArray()).Split(" ".ToCharArray());
			
			for(int j = 0; j < n; j++) {
				A[i,j] = int.Parse(cells[j]);
			}
		}
		
		List<Side> S = new List<Side>();
		
		//?\?????¨?§???¨?????§?´???£???¨?\???????????\?????\?????????\?\?????£?????¨?????£???¨?£?????£?????\?????\?????£?????£?????£????
		for(int i = 0; i < n; i++) {
			for(int j = i +1; j < n; j++) {
				if(A[i,j] != -1) S.Add(new Side(i,j,A[i,j]));
			}
		}
		
		S.Sort((a,b) => a.len - b.len);
		
		InitializeUnionFind(n);
		int ans = 0;
		for(int i = 0; i < S.Count(); i++) {
			Side e = S[i];
			
			if(!Same(e.a, e.b)) {
				Unite(e.a, e.b);
				ans += e.len;
			}
		}
		
		Console.WriteLine(ans);
	}
	
	public static bool Same(int x, int y)
	{
		return (Find(x) == Find(y));
	}
	
	public static int Find(int x)
	{
		if(parent[x] == x) return x;
		else return parent[x] = Find(parent[x]);
	}
	
	public static void Unite(int x, int y)
	{
		x = Find(x);
		y = Find(y);
		
		if(x == y) return;
		
		if(rank[x] < rank[y]) {
			parent[x] = y;
		} else {
			parent[y] = x;
			
			if(rank[x] == rank[y]) rank[x]++;
		}
	}
	
	public static void InitializeUnionFind(int n)
	{
		parent = new int[n];
		rank = new int[n];
		
		for(int i = 0; i < n; i++) {
			parent[i] = i;
		}
	}
}

public class Side
{
	public int a { private set; get; }
	public int b { private set; get; }
	public int len { private set; get; }
	
	public Side (int v1, int v2, int v3)
	{
		a	= v1;
		b	= v2;
		len	= v3;
	}
}