Go: package main

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

// Define disjoint-set forests

type vertexNo int

type vertex struct {
	number vertexNo
	rank int
	parent *vertex
}

func makeSet(number vertexNo) vertex {
	return vertex {
		number: number,
		rank: 0,
		parent: nil,
	}
}

func union(x, y *vertex) *vertex {
	return link(findSet(x), findSet(y))
}

func link(x, y *vertex) *vertex {
	if x.rank > y.rank {
		y.parent = x
		return x
	} else {
		x.parent = y
		if x.rank == y.rank {
			y.rank += 1
		}
		return y
	}
}

func findSet(v *vertex) *vertex {
	if v.parent == nil {
		return v
	}
	v.parent = findSet(v.parent)
	return v.parent
}

// Function to calculate minimum spanning tree

type matrix [][]int

type edge struct {
	one vertexNo
	two vertexNo
	weight int
}

const(
	MAX_VERTICES = 100
)

func newEdgesFromMatrix(matrix matrix) []edge {
	edges := make([]edge, 0, MAX_VERTICES * MAX_VERTICES)

	for i := 0; i < len(matrix); i++ {
		row := matrix[i]
		for j := i; j < len(row); j++ {
			if row[j] >= 0 {
				edge := edge{one: vertexNo(i+1), two: vertexNo(j+1), weight: row[j]}
				edges = append(edges, edge)
			}
		}
	}

	return edges
}

func solve(matrix matrix) int {
	nVertices := len(matrix)

	// initialize vertices
	vertices := make([]vertex, nVertices)
	for i := 0; i < nVertices; i++ {
		vertices[i] = makeSet(vertexNo(i+1))
	}

	// prepare edges sorted in the ascending order of weight
	edges := newEdgesFromMatrix(matrix)
	sort.Slice(edges, func(i, j int) bool {
		return edges[i].weight < edges[j].weight
	})

	unionCount := 0
	weightSum := 0
	for unionCount < nVertices-1 {
		for i := 0; i < len(edges); i++ {
			edge := edges[i]
			v1 := &vertices[edge.one-1]
			v2 := &vertices[edge.two-1]
			rep1 := findSet(v1)
			rep2 := findSet(v2)
			if rep1.number == rep2.number {
				continue
			}
			union(rep1, rep2)
			edges = append(edges[0:i], edges[i+1:]...)
			weightSum += edge.weight
			unionCount++
			break
		}
	}

	return weightSum
}

// main

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)

	n, err := nextInt(sc)
	if err != nil {
		panic(err)
	}

	matrix := parseMatrix(n, sc)

	edges := newEdgesFromMatrix(matrix)
	sort.Slice(edges, func(i, j int) bool {
		return edges[i].weight < edges[j].weight
	})

	fmt.Println(solve(matrix))
}

func parseMatrix(n int, sc *bufio.Scanner) [][]int {
	matrix := make([][]int, n)
	for i := 0; i < n; i++ {
		matrix[i] = make([]int, n)
		for j := 0; j < n; j++ {
			x, err := nextInt(sc)
			if err != nil {
				panic(err)
			}
			matrix[i][j] = x
		}
	}
	return matrix
}

func nextText(sc *bufio.Scanner) string {
	sc.Scan()
	return sc.Text()
}

func nextInt(sc *bufio.Scanner) (int, error) {
	return strconv.Atoi(nextText(sc))
}

C++: #include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <string>
#include <queue>
using namespace std;
const int MAXN = 10005;
const int INF = 1 << 30;
const int NIL = -1;
struct Node {
	int v, w, next;	//u->v
	friend bool operator<(const Node& a, const Node& b)
	{
		return a.w > b.w;
	}
	Node() {}
	Node(int vv, int ww) : v(vv), w(ww) {}
};
int cnt;
int head[MAXN];
Node edge[MAXN];




int prim(int n)
{
	
	bool vis[MAXN]{ false };
	priority_queue<Node> q;
	vis[1] = true;

	for (int i = head[1]; i != NIL; i = edge[i].next)
		q.push(edge[i]);
	int count = 0;
	int ans = 0;
	Node t;
	while (count < n - 1)
	{
		t = q.top();
		q.pop();
		if (vis[t.v])
			continue;
		vis[t.v] = true;
		ans += t.w;
		++count;
		for (int i = head[t.v]; i != NIL; i = edge[i].next)
			if (!vis[edge[i].v])
				q.push(edge[i]);

	}
	
	return ans;
}


void add(int u, int v, int w)
{
	edge[cnt].v = v;
	edge[cnt].w = w;
	edge[cnt].next = head[u];
	head[u] = cnt++;
}



int main(void)
{
	int n, m, u, v, w;
	scanf("%d", &n);
	int N = n * n;
	for (int i = 0; i <= N; ++i)
		head[i] = NIL;
	cnt = 0;
	for (int i = 1; i <= n; ++i)
	{
		for (int j = 1; j <= n; ++j)
		{
			scanf("%d", &w);
			if (w != NIL)
				add(i, j, w);
		}
	}
	cout << prim(n) << endl;
	return 0;
}

C++: #include <iostream>
#include <utility>
#include <string>
#include <algorithm>
#include <set>
#include <deque>
#include <vector>
#define MAX 150
#define rep(i,p) for(int i=0;i<p;i++)
#define rep1(i,p) for(int i=1;i<=p;i++)
#define pb push_back
using namespace std;
int n,temp,a,b,size;
int A[MAX];
int B[MAX];
int W[MAX];
int V[MAX];
pair<int,int> edge[MAX];

int root (int child) {
  int a = child;
  while (V[a] != a) {
    a = V[a];
  }
  return a;
}

int main(){
  size = 0;
  cin >> n;
  rep(i,n) 
    rep(j,n) {
      cin >> W[size];
      if (i <= j) {        
        A[size] = i;
        B[size] = j;
        edge[size].first = W[size];
        edge[size].second = size;
        size++;
      }
    }

  // sort by lenght of edge
  sort(edge, edge+size+1);
  // printing
  // rep(i,size+1) {
  //   cout << A[edge[i].second] << " " << B[edge[i].second]
  //        << " " << edge[i].first << endl;;
  // }
  int sum = 0;
  rep(i,n) V[i] = i;
  rep(i,size) {
    if (edge[i].first == -1) continue;
    temp = edge[i].second;
    // a , b : vertex
    a = A[temp]; 
    b = B[temp];
    if (root(a) != root(b)) {
      // ?????????????????????
      sum += edge[i].first;
      if (root(a) != a && root(b) == b){        
        V[b] = a;
      } else if (root(a) == a && root(b) != b) {
        V[a] = b;
      } else if (root(a) == a && root(b) == b) {        
        V[a] = b;
      }
    } else {
    }
  }
  cout << sum << endl;
  return 0;
}

C++: //Minimum Spannig Tree
#include <iostream>
#include <vector>
#include <climits>

using namespace std;

static const int N = 100;
static const int WHITE = 0;
static const int BLACK = 1;

int prim(vector<vector<int>> &G, int n) {
    int colors[n], d[n];
    for(int i = 0; i < n; i++) {
        colors[i] = WHITE;
        d[i] = INT_MAX;
    }

    d[0] = 0;
    int l = 0;
    while(1) {
        int u = -1;
        int mincost = INT_MAX;
        for(int i = 0; i < n; i++) {
            if(colors[i] == WHITE && d[i] < mincost) {
                mincost = d[i];
                u = i;
            }
        }
        if(u == -1) break;
        colors[u] = BLACK;
        l += mincost;
        for(int v = 0; v < n; v++)
            if(colors[v] == WHITE && G[u][v] != -1)
                if(G[u][v] < d[v])
                    d[v] = G[u][v];
    }
    return l;
}

int main() {
    int n;
    cin >> n;
    vector<vector<int>> G(n, vector<int>(n));
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
            cin >> G[i][j];

    cout << prim(G, n) << endl;
}