Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

func nextString() string {
	scanner.Scan()
	return scanner.Text()
}

func nextInt() int {
	n, err := strconv.Atoi(nextString())
	if err != nil {
		fmt.Printf("strconv.Atoi failed: %v\n", err)
	}
	return n
}

type ElementKey int
type Node struct {
	key    ElementKey
	parent *Node
	rank   int
}

func newNode(key ElementKey) *Node {
	node := Node{}
	node.key = key
	node.parent = &node
	node.rank = 0

	return &node
}

func union(x, y *Node) {
	xSet := findSet(x)
	ySet := findSet(y)
	link(xSet, ySet)
}

func link(x, y *Node) {
	if x.rank > y.rank {
		y.parent = x
	} else {
		x.parent = y

		if x.rank == y.rank {
			y.rank++
		}
	}
}

func findSet(x *Node) *Node {
	if x != x.parent {
		x.parent = findSet(x.parent)
	}
	return x.parent
}

func newDisjointSets(nSets int) *DisjointSets {
	sets := DisjointSets{}
	sets.keyToNode = map[ElementKey]*Node{}
	for i := 0; i < nSets; i++ {
		key := ElementKey(i)
		sets.keyToNode[key] = newNode(key)
	}
	return &sets
}

type DisjointSets struct {
	keyToNode map[ElementKey]*Node
}

func (sets *DisjointSets) union(x, y ElementKey) {
	xNode := sets.keyToNode[x]
	yNode := sets.keyToNode[y]
	union(xNode, yNode)
}

func (sets DisjointSets) findSet(x ElementKey) *Node {
	xNode := sets.keyToNode[x]
	return findSet(xNode)
}

type Edge struct {
	i, j   int
	weight int
}

func main() {
	scanner.Split(bufio.ScanWords)

	n := nextInt()
	sets := newDisjointSets(n)
	edges := []Edge{}
	a := make([][]int, n)
	for i := 0; i < n; i++ {
		a[i] = make([]int, n)
		for j := 0; j < n; j++ {
			a[i][j] = nextInt()
			if a[i][j] >= 0 {
				e := Edge{
					i:      i,
					j:      j,
					weight: a[i][j],
				}
				edges = append(edges, e)
			}
		}
	}
	sort.Slice(edges, func(i, j int) bool { return edges[i].weight < edges[j].weight })
	totalWeight := 0
	for _, edge := range edges {
		i := ElementKey(edge.i)
		j := ElementKey(edge.j)
		if sets.findSet(i) != sets.findSet(j) {
			totalWeight += edge.weight
			sets.union(i, j)
		}
	}
	fmt.Println(totalWeight)
}

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

int n; // number of vertices 
int P[20200], A[20200], B[20200], C[20200];
pair<int, int> D[20200]; // Weights and coordinates 

int root(int a) { // find the root of a
  if (P[a] == a) return a; // a is the root
  return  (P[a] = root(P[a])); // find root of a, make it a's parent
}

bool is_same_set(int a, int b) { // a and b are in the same group?
  return root(a) == root(b);
}

void unite(int a, int b) { // put a and b in same group
  P[root(a)] = root(b);
}


int main() {
  cin >> n; // the number of vertices
  for (int i=0; i<n; ++i) {
    P[i] = i; // Initialize vertices to disjoint sets
    for (int j=0; j<n; ++j) {
      A[(n * i) + j] = i;
      B[(n * i) + j] = j;
      cin >> C[(n * i) + j];
    }
  }
  for (int i=0; i < n*n; i++) {
    D[i].first = C[i];
    D[i].second = i;
  }
  sort(D, D+n*n);
  int sum = 0;

  for (int i=0; i<n*n; ++i) {
    if (D[i].first >= 0) { // Assuming the weight is not -1
      if (!is_same_set(A[D[i].second], B[D[i].second])) {
	unite(A[D[i].second], B[D[i].second]);
	sum += D[i].first;
      }
    }
  }
  cout << sum << endl;
}

C++: #include <iostream>

using namespace std;

#define N_MAX 100
#define W_MAX 2000

int Adj[N_MAX][N_MAX] = {};

int color[N_MAX] = {};

int sum_mst_path = 0;
int n;

int prim(void);

int main(){
    int i, j;

    cin >> n;
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            cin >> Adj[i][j];
        }
    }

    color[0] = 1;
    while ( prim() );

    cout << sum_mst_path << endl;

    return 0;
}

//[?????????
//0 : MST????§???????????????????
//1 : ???????????????????????????
int prim(void) {
    int i, j, min, next_node;

    min = W_MAX + 1;
    next_node = N_MAX + 1;

    //?¢????node???????????????????¢????node??????????????§???????°??????¢???path?????¢?´¢
    for (i = 0; i < n; i++) {
        if (color[i] != 1)
            continue;

        for (j = 0; j < n; j++) {
            if (color[j] != 0)
                continue;

            if (Adj[i][j] != -1 && Adj[i][j] < min) {
                min = Adj[i][j];
                next_node = j;
            }
        }
    }

    if (next_node == N_MAX + 1) //??????????¢??????????
        return 0;

    //next_node????¢????
    color[next_node] = 1;
    sum_mst_path += min;

    return 1;
}

C++: #include <algorithm>
#include <iostream>
#include <vector>
#include <math.h>
#include <set>
#include <map>
#include <string>
#include <stack>
#include <queue>
#include <iomanip>
#include <numeric>
#include <tuple>
#define _USE_MATH_DEFINES
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef tuple<int, int, int> tiii;
double pi = 3.141592653589793;
ll mod = 1000000007;
int intmax = 2147483647;
int intmin = -2147483648;
ll llmax = 9223372036854775807;
ll llmin = -9223372036854775807;

struct unionFind {
    vector<int> data;
    unionFind(int size) : data(size, -1) {}
    
    bool unite(int x, int y) {
        x = root(x);
        y = root(y);
        if (x != y) {
            if(data[y] < data[x]) {
                swap(x, y);
            }
            data[x] += data[y];
            data[y] = x;
        }
        return x != y;
    }

    bool same(int x, int y) {
        return root(x) == root(y);
    }

    int root(int x) {
        return (data[x] < 0) ? x : data[x] = root(data[x]);
    }

    int rank(int x) {
        return -data[root(x)];
    }
};

//cost,from,toの順
vector<tiii> T;
vector<tiii> Krusans;

ll Kruskal(int n) {
    sort(T.begin(), T.end());
    ll ans = 0;
    ll num = 0;
    unionFind u(n);
    int size = T.size();
    for (int i = 0; i < size; i++) {
        int cost = get<0>(T[i]);
        int from = get<1>(T[i]);
        int to = get<2>(T[i]);
        if (u.root(from) != u.root(to)) {
            u.unite(from, to);
            ans += cost;
            num++;
            tiii t = make_tuple(cost, from, to);
            Krusans.push_back(t);
        }
        if (num == n - 1) {
            break;
        }
    }
    return ans;
}

int mat[200][200];

int main() {
    int N;
    cin >> N;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            cin >> mat[i][j];
        }
    }
    for (int i = 0; i < N; i++) {
        for (int j = i + 1; j < N; j++) {
            if (mat[i][j] != -1) {
                tiii e = make_tuple(mat[i][j], i, j);
                T.push_back(e);
            }
        }
    }
    ll ans = Kruskal(N);
    cout << ans << endl;
}