Go: package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
)

var (
	n int
	M [MAX][MAX]int
)

const MAX = 100
const WHITE = 0
const GRAY = 1
const BLACK = 2

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	sc.Scan()
	n, _ = strconv.Atoi(sc.Text())

	for i := 0; i < n; i++ {
		for j := 0; j < n; j++ {
			sc.Scan()
			c, _ := strconv.Atoi(sc.Text())
			if c != -1 {
				M[i][j] = c
			} else {
				M[i][j] = math.MaxInt64
			}

		}
	}
	prim()
}

func prim() {
	var u int
	var minv int
	var d [MAX]int
	var p [MAX]int
	var color [MAX]int

	for i := 0; i < n; i++ {
		d[i] = math.MaxInt64
		p[i] = -1
		color[i] = WHITE
	}

	d[0] = 0

	for {
		minv = math.MaxInt64
		u = -1
		for i := 0; i < n; i++ {
			if minv > d[i] && color[i] != BLACK {
				u = i
				minv = d[i]
			}
		}

		if u == -1 {
			break
		}

		color[u] = BLACK

		for v := 0; v < n; v++ {
			if color[v] != BLACK && M[u][v] != math.MaxInt64 {
				if d[v] > M[u][v] {
					d[v] = M[u][v]
					p[v] = u
					color[v] = GRAY
				}
			}
		}
	}
	sum := 0
	for i := 0; i < n; i++ {
		if p[i] != -1 {
			sum += M[i][p[i]]
		}
	}
	fmt.Println(sum)

}

C++: #if 0
????????????????§£????????????????????????????????????????????????AOJ????????????????????????????????????wrong???answer?????????????????????
????????§?????????????????\????????????????????£??????????????§??????????????????????????????????????¨???????????????
???????????????????????? Union Find Tree ???????????????????????????????????????????????????????????????????????????Root?????¢?????°??????????????¨??§??????
??????????????§???????????????????????????????????????????????¢??°???????????¢??°?????????????????£??????????????°???????????°???????\???????????????¨???????????¨???
????????????????????????
Minimum Spanning Tree ???????????§???????????¶??????????????????????????¨????????????????????¨?????????????????????????????????????????????????????£?????????
???????????????????????????????????????
#endif

#include <iostream>
#include<algorithm>
using namespace std;


struct edge
{
   int cost;
   int src;
   int dst;
};

edge e[5000];
int A[100][100];
int M=0;
int P[100];

void init(int N)
{
  for (int i=0; i<=N; ++i) P[i] = i;
}

int root(int a)
{
  if (P[a] == a) return a;
  return (P[a] = root(P[a]));
}

bool is_same_set(int a, int b)
{
  return root(a) == root(b);
}

void unite(int a, int b)
{
  P[root(a)] = root(b);
}

void checkEdges(int n)
{
    for(int r=0;r<n;r++)
    {
        for(int c=r+1;c<n;c++)
            {
                if(A[r][c]>-1)
                    {
                        e[M].cost=A[r][c];
                        e[M].src=r;
                        e[M].dst=c;
                        M+=1;
                    }
            }
    }
}

bool cmp(edge e1,edge e2)
{
    return e1.cost<=e2.cost;
}
int main()
{
    int n,count=0;
    cin>>n;
    init(n);
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++){
                cin>>A[i][j];
        }
    }
    checkEdges(n);
    sort(e,e+M,cmp);
    for (int i=0; i<M; ++i)
    {
        if(is_same_set(e[i].src,e[i].dst))
        {
            continue;
        }
        unite(e[i].dst,e[i].src);
        count+=e[i].cost;
    }
    cout<<count<<endl;
    return 0;
}

C++: #include <iostream>
#include<algorithm>
using namespace std;


struct edge
{
   int cost;
   int src;
   int dst;
};

edge e[5000];
int A[100][100];
int M=0;
int P[100];

void init(int N)
{
  for (int i=0; i<=N; ++i) P[i] = i;
}

int root(int a)
{
  if (P[a] == a) return a;
  return (P[a] = root(P[a]));
}

bool is_same_set(int a, int b)
{
  return root(a) == root(b);
}

void unite(int a, int b)
{
  P[root(a)] = root(b);
}

void checkEdges(int n)
{
    for(int r=0;r<n;r++)
        for(int c=r+1;c<n;r++)
    {
        if(A[r][c]>-1)
        {
            e[M].cost=A[r][c];
            e[M].src=r;
            e[M].dst=c;
            M+=1;
        }
    }
}

bool cmp(edge e1,edge e2)
{
    return e1.cost<=e2.cost;
}
int main()
{
    int n,count=0;
    cin>>n;
    init(n);
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++){
                cin>>A[i][j];
        }
    }
    checkEdges(n);
    sort(e,e+M,cmp);
    for (int i=0; i<M; ++i)
    {
        if(is_same_set(e[i].src,e[i].dst))
        {
            continue;
        }
        unite(e[i].dst,e[i].src);
        count+=e[i].cost;
    }
    cout<<count<<endl;
    //system("pause");
    return 0;
}