Go: package main

import (
	"fmt"
	"sort"
)

type Edge struct {
	I int
	J int
	A int
}

func main() {
	var n int
	fmt.Scan(&n)

	g := make([][]int, n)
	edges := make([]Edge, 0, n*(n-1)/2)
	parents := make([]int, n)
	for i := 0; i < n; i++ {
		g[i] = make([]int, n)
		for j := 0; j < n; j++ {
			fmt.Scan(&g[i][j])
			if g[i][j] > 0 {
				edges = append(edges, Edge{i, j, g[i][j]})
			}
		}
		parents[i] = i
	}
	sort.SliceStable(edges, func(i, j int) bool { return edges[i].A > edges[j].A })

	sum := 0
	for len(edges) > 0 {
		edge := edges[len(edges)-1]
		edges = edges[:len(edges)-1]

		if same(edge.I, edge.J, &parents) {
			continue
		}
		union(edge.I, edge.J, &parents)
		sum += edge.A
	}
	fmt.Println(sum)
}



func root(id int, parents *[]int) int {
	if id == (*parents)[id] {
		return id
	}
	return root((*parents)[id], parents)
}

func union(i, j int, parents *[]int) {
	(*parents)[root(j, parents)] = (*parents)[root(i, parents)]
}

func same(i, j int, parents *[]int) bool {
	return root(i, parents) == root(j, parents)
}

C++: #include<iostream>
#include<vector>
#include<algorithm>

#define MAX_NODE 10000

using namespace std;

typedef struct{
	int from,to,weight;
} Edge;

typedef struct{
	int parent,rank;
} Node;

Node node[MAX_NODE];
vector<Edge> edge;

void init(int n){
	for(int i=0;i<n;i++){
		node[i].parent=i;
		node[i].rank=0;
	}
}

int find(int n){
	return node[n].parent==n?n:node[n].parent=find(node[n].parent);
}

void unite(int x,int y){
	int xr=find(x);
	int yr=find(y);
	if(node[xr].rank>node[yr].rank){
		node[yr].parent=node[xr].parent;
	}else if(xr!=yr){
		node[xr].parent=node[yr].parent;
		if(node[xr].rank==node[yr].rank){
			node[yr].rank++;
		}
	}
}

bool operator<(const Edge& left,const Edge& right){
	return (left.weight<right.weight?1:0);
}

int main(){
	int n,tmp,w=0;
	Edge e;
	cin>>n;
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			cin>>tmp;
			if(tmp!=-1){
				e.from=i;
				e.to=j;
				e.weight=tmp;
				edge.push_back(e);
			}
		}
	}
	sort(edge.begin(),edge.end());
	init(n);
	for(int i=0;i<edge.size();i++){
		if(find(edge[i].from)==find(edge[i].to)){
			continue;
		}
		w+=edge[i].weight;
		unite(edge[i].from,edge[i].to);
	}
	cout<<w<<endl;
	return 0;
}

C++: #include <iostream>
#include <ios>
#include <vector>
#include <queue>
#include <utility>
#include <tuple>

using namespace std;
int Es[100][100] = {{0}};

int MST(int n){
    vector<bool> used(n, false);
    priority_queue< pair<int, int> > pq;
    pq.emplace(0, 0);
    int dist = 0;
    int node = 0;
    int total_dist = 0;
    while (! pq.empty()){
        tie(dist, node) = pq.top();
        pq.pop();
        if (used[node]) continue;
        used[node] = true;
        total_dist -= dist;
        for (int new_node = 0; new_node != n; ++new_node){
            if (used[new_node] || Es[node][new_node] == -1) continue;
            pq.emplace(-Es[node][new_node], new_node);
        }
    }
    return total_dist;
}

int main()
{
    ios::sync_with_stdio(false);
    int n = 0;
    cin >> n;
    for (int i = 0; i != n; ++i){
        for (int j = 0; j != n; ++j){
            cin >> Es[i][j];
        }
    }
    cout << MST(n) << endl;
    return 0;
}

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

#define check cout<<"-------"<<endl
#define debug(x) cout<<x<<endl

#define N 101
#define MAX 2001

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    int a[N][N];
    int list[MAX];
    
    int n;
    cin>>n;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            cin>>a[i][j];
        }
    }
    
    int sum = 0, min, mini, i, j;
    int lp = n-1;
    list[0] = 1;
    for(i = 1; i <= n; i++) a[i][1] = -1;
    while(lp--) {
        min = 2001;
        for(i = 0; list[i] !=0; i++) {
            for(j = 1; j <= n; j++) {
                if(min > a[ list[i] ][j] && a[ list[i] ][j] != -1) {
                    min = a[ list[i] ][j];
                    mini = j;
                }
            }
        }
        sum += min;
        list[i] = mini;
        for(int j = 1; j <= n; j++) a[j][mini] = -1;
    }
    
    cout<<sum<<endl;
    
    return 0;
}

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

struct edge {int u, v, cost;};

int n;
vector<edge> G;

bool comp(const edge& e1, const edge& e2) {
    return e1.cost < e2.cost;
}

class UnionFind {
 public:
    int g_num;
    vector<int> rank, par;

    UnionFind() {}
    UnionFind(int size) {
        rank.resize(size, 0);
        par.resize(size, 0);
        for (int i = 0; i < size; i++) {
            par[i] = i;
            rank[i] = 0;
        }
        g_num = size;
    }

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

    void unite(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) return;

        g_num--;
        if (rank[x] > rank[y]) {
            par[y] = x;
        } else {
            par[x] = y;
            if (rank[x] == rank[y]) rank[y]++;
        }
    }

    int find(int x) {
        if (x == par[x]) return x;
        return par[x] = find(par[x]);
    }

    int group_num() {
        return g_num;
    }
};

int kruskal() {
    sort(G.begin(), G.end(), comp);
    UnionFind uf(n);
    int res = 0;
    for (auto e: G) {
        if (!uf.same(e.u, e.v)) {
            uf.unite(e.u, e.v);
            res += e.cost;
        }
    }
    return res;
}

int main(void) {
    cin >> n;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            int cost;
            cin >> cost;
            if (cost == -1) continue;
            G.push_back(edge {i, j, cost});
        }
    }
    int ans = kruskal();
    cout << ans << endl;
    return 0;
}

C++: // #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(v) v.begin(), v.end()
#define Graph vector< vector<int> >
typedef long long ll;
typedef pair<int, int> P;
const int INF = 1000000007;

int main(){
    int N;
    cin >> N;
    Graph M(N, vector<int>(N));
    rep(i, N){
        rep(j, N){
            cin >> M[i][j];
            if(M[i][j] == -1) M[i][j] = INF;
        }
    }

    vector<int> d(N, INF), p(N, -1);
    vector<bool> visited(N);
    d[0] = 0;
    p[0] = -1;
    int sum = 0;

    while(1){
        int mincost = INF;
        int u;
        rep(i, N){
            if( !visited[i] && d[i] < mincost){
                mincost = d[i];
                u = i;
            }
        }

        if(mincost == INF) break;
        sum += d[u];
        visited[u] = true;

        rep(v, N){
            if( !visited[v] && M[u][v] != INF){
                if(M[u][v] < d[v]){
                    d[v] = M[u][v];
                    p[v] = u;
                }
            }
        }
    }
    
    cout << sum << endl;

}