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.Linq;

namespace ALDS1_12_A
{
    class Program
    {
        private static int n;
        private static int[,] neigborWeights;
        private static int[] d;

        private static bool[] isVisited;
        static void Main(string[] args)
        {
            Program.n = int.Parse(Console.ReadLine());
            Program.d = new int[Program.n];
            Program.isVisited = new bool[Program.n];
            Program.neigborWeights = new int[Program.n, Program.n];
            for (int i = 0; i < Program.n; i++)
            {
                int[] tmpLine = Console.ReadLine()
                                        .Trim(' ')
                                        .Split(' ')
                                        .Select(s => int.Parse(s))
                                        .ToArray();
                for (int j = 0; j < Program.n; j++)
                {
                    Program.neigborWeights[i, j] = tmpLine[j];
                }
                Program.d[i] = (int)Math.Pow(10, 7);
            }
            Program.d[0] = 0;

            int minSumWeight = 0;
            MinHeap minHeap = new MinHeap(Program.n);
            while(minHeap.maxIndex >= 0)
            {
                int vertex = minHeap.Dequeue(Program.d);
                Program.isVisited[vertex] = true;
                minSumWeight += d[vertex];
                for (int i = 0; i < Program.n; i++)
                {
                    if
                    (   Program.neigborWeights[vertex, i] >= 0
                    &&  !Program.isVisited[i]
                    &&  Program.d[i] > Program.neigborWeights[vertex, i]
                    )
                    {
                        Program.d[i] = Program.neigborWeights[vertex, i];
                        minHeap.UpHeapfy(i, Program.d);
                    }
                }
            }
            Console.WriteLine(minSumWeight);
        }
    }
    class MinHeap
    {
        private int[] heap;
        private int[] vertexIndex;
        public int maxIndex;
        public MinHeap(int heapSize)
        {
            this.heap = new int[heapSize];
            this.vertexIndex = new int[heapSize];
            for (int i = 0; i < heapSize; i++)
            {
                this.heap[i] = i;
                this.vertexIndex[i] = i;
            }
            this.maxIndex = heapSize - 1;
        }
        
        public int Dequeue(int[] d)
        {
            int returnVal = this.heap[0];
            this.vertexIndex[this.heap[0]] = -1;
            this.heap[0] = this.heap[this.maxIndex];
            this.vertexIndex[this.heap[this.maxIndex]] = 0;
            this.maxIndex--;
            this.DownHeapfy(this.heap[0], d);
            return returnVal;
        }
        public void DownHeapfy(int vertex, int[] d)
        {
            int tmpIndex = this.vertexIndex[vertex];
            int leftIndex = (tmpIndex + 1) * 2 - 1;
            int rightIndex = (tmpIndex + 1) * 2;
            if (leftIndex <= this.maxIndex && d[this.heap[leftIndex]] < d[this.heap[tmpIndex]])
            {
                tmpIndex = leftIndex;
            }
            if (rightIndex <= this.maxIndex && d[this.heap[rightIndex]] < d[this.heap[tmpIndex]])
            {
                tmpIndex = rightIndex;
            }
            if (tmpIndex != this.vertexIndex[vertex])
            {
                int parent = vertex;
                int parentIndex = this.vertexIndex[parent];
                int tmp = this.heap[tmpIndex];
                
                this.heap[parentIndex] = tmp;
                this.heap[tmpIndex] = parent;

                this.vertexIndex[parent] = tmpIndex;
                this.vertexIndex[tmp] = parentIndex;

                this.DownHeapfy(vertex, d);
            }
            return;
        }

        public void UpHeapfy(int vertex, int[] d)
        {
            int vertexIndex = this.vertexIndex[vertex];
            if (vertexIndex == 0)
            {
                return;
            }
            int parentIndex = (vertexIndex + 1) / 2 - 1;
            int parent = this.heap[parentIndex];
            if (d[vertex] < d[parent])
            {
                this.heap[vertexIndex] = parent;
                this.vertexIndex[vertex] = parentIndex;

                this.heap[parentIndex] = vertex;
                this.vertexIndex[parent] = vertexIndex;

                this.UpHeapfy(vertex, d);
            }
            return;
        }
    }
}