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
	num := 0
	for len(edges) > 0 && num < n-1 {
		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
		num += 1
	}
	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 <cstdio>
#include <cctype>
#include <vector>
#include <queue>
using namespace std;

#define si static inline
#define gcu getchar_unlocked
si int in() {
	int c, n = 0;
	bool minus = false;
	if ((c = gcu()) == '-') minus = true; else ungetc(c, stdin);
	while ((c = gcu()) >= '0' && c <= '9') n = 10 * n + (c - '0');
	//return n; }
	return minus ? -n : n; }
si void scan(char *s) {while (!isspace(*s++ = gcu()));}
#define pcu putchar_unlocked
#define svo si void out
template <typename T>
svo(T n) {
	static char buf[20];
	char *p = buf;
	//if(n < 0) pcu('-'), n *= -1;
	if (!n) *p++ = '0';
	else while (n) *p++ = n % 10 + '0', n /= 10;
	while (p != buf) pcu(*--p); }
svo(const char *s){while(*s)pcu(*s++);}
svo(char *s){while(*s)pcu(*s++);}
svo(char c){pcu(c);}
template <typename T>
//svo(vector<T> &v){for(T &x:v)out(' '),out(x);out('\n');}
svo(vector<T> &v){for(T &x:v)out(&x == &v[0]?"":" "),out(x);out('\n');}
template <typename head, typename... tail>
svo(head&& h, tail&&... t){out(h);out(move(t)...);}
#undef svo
#undef si

#define v vector
struct graph {
	struct node {int n, w;};
	v<v<node>> nodes;

	void read(int n) {
		nodes.resize(n);
		for (auto &x: nodes) {
			gcu();
			for (int i = 0, w; i < n; i++)
				if ((w = in()) != -1)
					x.push_back({i, w});
		}
	}

	int mst_prim() {
		int w = 0;
		v<bool> visited(nodes.size());
		priority_queue<node> q;
		q.push({0, 0});
		while (!q.empty()) {
			node n = q.top();
			q.pop();
			if (visited[n.n])
				continue;
			w += n.w;
			visited[n.n] = true;
			for (node &i: nodes[n.n])
				q.push(i);
		}

		return w;
	}
};

bool operator < (const graph::node &a, const graph::node &b) {
	return a.w > b.w;
}

int main() {
	graph g;
	g.read(in());
	out(g.mst_prim(), '\n');
}

C++: #include<iostream>
using namespace std;
static const int MAX=100;
static const int INFTY=(1<<21);
static const int WHITE=0;
static const int GRAY=1;
static const int BLACK=2;

int n,m[MAX][MAX];

int prim(){
  int u,minv;
  int d[MAX],p[MAX],color[MAX];

  for(int i=0;i<n;i++){
    d[i]=INFTY;
    p[i]=-1;
    color[i]=WHITE;
  }

  d[0]=0;

  while(1){
    minv=INFTY;
    u=-1;
    for(int 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(int v=0;v<n;v++){
      if(color[v]!=BLACK&&m[u][v]!=INFTY){
	if(d[v]>m[u][v]){
	  d[v]=m[u][v];
	  p[v]=u;
	  color[v]=GRAY;
	}
      }
    }
  }
  int sum=0;
  for(int i=0;i<n;i++){
    if(p[i]!=-1) sum+=m[i][p[i]];
  }
  return sum;
}

int main(){
  cin>>n;
  for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
      int e;
      cin>>e;
      m[i][j]=(e==-1)?INFTY:e;
    }
  }
  cout<<prim()<<endl;

  return 0;
}

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

int P[10010];

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

int root(int a) {
	if (P[a] == a) {
		return a;
	} else {
		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);
}

int main() {
	int n; // the number of vertcies
	std::cin >> n;
	// input the numbers
	std::tuple<int, int, int> a[n * n];
	int count = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			std::cin >> std::get<0>(a[count]);
			std::get<1>(a[count]) = i;
			std::get<2>(a[count]) = j;
			count++;
		}
	}
	
	// sort hte tree by weight
	std::sort(a, a + n * n);
	
	// Krukas algorithm
	// set the tree
	init(n * n);
	
	int sum = 0;
	for (int i = 0; i < n * n; i++) {
		if (std::get<0>(a[i]) != -1) {
			if(! is_same_set(P[std::get<1>(a[i])], P[std::get<2>(a[i])])) {
				unite(P[std::get<1>(a[i])], P[std::get<2>(a[i])]);
				sum += std::get<0>(a[i]);
			}
		}
	}
	std::cout << sum <<std::endl;
}

C++: #include <bits/stdc++.h>
#define ll long long
#define INF 1000000005
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define spair(p) cout<<#p<<": "<<p.fi<<" "<<p.se<<endl
#define svec(v) cout<<#v<<":";rep(kbrni,v.size())cout<<" "<<v[kbrni];cout<<endl
#define sset(s) cout<<#s<<":";each(kbrni,s)cout<<" "<<kbrni;cout<<endl
#define smap(m) cout<<#m<<":";each(kbrni,m)cout<<" {"<<kbrni.first<<":"<<kbrni.second<<"}";cout<<endl

using namespace std;

typedef pair<int,int> P;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<double> vd;
typedef vector<P> vp;
typedef vector<string> vs;

class UF {
private:
    int sz; vector<int> par,nrank;
public:
    UF(){}
    UF(int node_size){ sz = node_size; par.resize(sz),nrank.resize(sz); rep(i,sz){ par[i] = i; nrank[i] = 0; } }
    int find(int x){ if(par[x] == x){ return x; }else{ return par[x] = find(par[x]); } }
    void unite(int x,int y)
    { x = find(x),y = find(y); if(x == y) return;
    	if(nrank[x] < nrank[y]){ par[x] = y; }else{ par[y] = x; if(nrank[x] == nrank[y]) nrank[x]++; } }
    bool same(int x,int y){ return find(x) == find(y); }
};

template<typename T> class Kruskal{
public:
	struct edge{
		int u,v;
		T cost;
		bool operator<(const edge& another) const {
			return cost < another.cost;
		}
	};
	vector<edge> es;
	vector<int> par,rrank;
	int V;
    Kruskal(int node_size){
        V = node_size;
		par.resize(node_size), rrank.resize(node_size);
	}
	void add_edge(int u,int v,T cost){
		es.push_back((edge){u,v,cost});
	}
	T make(){
		UF uf(V);
		T res = 0;
		int cnt = 0;
        sort(es.begin(),es.end());
		rep(i,es.size()){
			edge e = es[i];
			if(!uf.same(e.u,e.v)){
				uf.unite(e.u,e.v);
				res += e.cost;
				cnt++;
				if(cnt == V-1){
					break;
				}
			}
		}
		return res;
	}
};


int main()
{
    int n;
    cin >> n;
    Kruskal<int> kr(n);
    rep(i,n){
        rep(j,n){
            int a;
            cin >> a;
            if(i < j && a >= 0){
                kr.add_edge(i,j,a);
            }
        }
    }
    cout << kr.make() << "\n";
}