Go: package main

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

const (
	white int = iota
	gray
	black
)
const INFTY int = 2001

var G [][]int
var color []int
var d []int
var p []int
var N int

func prim() int {
	u := 0
	d[u] = 0
	for {
		minCost := INFTY
		for i:=0; i<N; i++ {
			if color[i] != black && d[i] < minCost {
				minCost = d[i]
				u = i
			}
		}

		if minCost == INFTY {
			break
		}

		color[u] = black

		for v:=0; v<N; v++ {
			if color[v] != black && G[u][v] != -1 {
				if G[u][v] < d[v] {
					d[v] = G[u][v]
					p[v] = u
					color[v] = gray
				}
			}
		}
	}
	// sum
	sum := 0
	for i:=0; i<N; i++ {
		if p[i] != -1 {
			sum += G[i][p[i]]
		}
	}
	return sum
}




func initVariable(N int) {
	G = make([][]int, N)
	for i:=0; i<N; i++ {
		G[i] = make([]int, N)
	}
	color = make([]int, N)
	d = make([]int, N)
	p = make([]int, N)
	for i:=0; i<N; i++ {
		d[i] = INFTY
		p[i] = -1
	}
}

func nextInt(scanner *bufio.Scanner) int {
	scanner.Scan()
	num, _ := strconv.Atoi(scanner.Text())
	return num
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	N = nextInt(scanner)
	initVariable(N)
	for i:=0; i<N; i++ {
		for j:=0; j<N; j++ {
			G[i][j] = nextInt(scanner)
		}
	}
	fmt.Printf("%d\n", prim())
}

C++: #include <bits/stdc++.h>
#define For(i, a, b) for(int (i)=(a); (i)<(b); ++(i))
#define rFor(i, a, b) for(int (i)=(a)-1; (i)>=(b); --(i))
#define rep(i, n) For((i), 0, (n))
#define rrep(i, n) rFor((i), (n), 0)
#define fi first
#define se second
using namespace std;
typedef long long lint;
typedef pair<int, int> pii;

typedef struct UnionFindTree{
  vector<int> par;
  vector<int> treerank;
  
  UnionFindTree(int n){
    par.resize(n); treerank.resize(n);
    rep(i, n) par[i] = i, treerank[i] = 0;
  }
  
  int find(int x){
    if(par[x] == x) return x;
    return par[x] = find(par[x]);
  }
  
  void unite(int x, int y){
    x = find(x); y = find(y);
    if(x == y) return;
    if(treerank[x] < treerank[y]) swap(x, y);
    if(treerank[x] == treerank[y]) treerank[x]++;
    par[y] = x;
    return;
  }
  
  bool same(int x, int y){
    return find(x) == find(y);
  }
}UF;
 
template<class T> struct edge{
    int from, to; T cost;
    edge(int f, int t, T c){
        from = f; to = t; cost = c;
    }
};
 
template<class T> struct Graph{
    vector<vector<edge<T>>> G;
    int n;
    
    Graph(int n_){
        n = n_;
        G.resize(n);
    }
    
    void add_edge(int f, int t, T c){
        G[f].emplace_back(f, t, c);
    }
    
    vector<T> dijkstra(int s){
        using P = pair<T, int>;
        priority_queue<P, vector<P>, greater<P>> que;
        vector<T> d(n, numeric_limits<T>::max());
        d[s] = 0;
        que.push(P((T)0, s));
        while(!que.empty()){
            P p = que.top(); que.pop();
            int v = p.second;
            if(d[v] < p.first) continue;
            for(edge<T> &e : G[v]){
                if(d[e.to] > d[v] + e.cost){
                    d[e.to] = d[v] + e.cost;
                    que.push(P(d[e.to], e.to));
                }
            }
        }
        return d;
    }
    
    T kruskal(){
        vector<edge<T>> E;
        rep(i, n)for(edge<T> &e: G[i]) E.push_back(e);
        sort(E.begin(), E.end(), [](const edge<T> &e1, const edge<T> &e2){return e1.cost < e2.cost;});
        UF uf(n);
        T res = 0;
        for(edge<T> &e: E){
            if(!uf.same(e.from, e.to)){
                uf.unite(e.from, e.to);
                res += e.cost;
            }
        }
        return res;
    }
    
    vector<int> toposo(){
        vector<int> ret(n), in(n, 0);
        rep(i, n)for(edge<T> &e: G[i]) ++in[e.to];
        int cur = 0;
        stack<int> st;
        rep(i, n)if(!in[i]) st.push(i);
        while(!st.empty()){
            int v = st.top(); st.pop();
            ret[cur++] = v;
            for(edge<T> &e: G[v]){
                --in[e.to];
                if(!in[e.to]) st.push(e.to);
            }
        }
        return ret;
    }
};

int main(){
    int n;
    scanf("%d", &n);
    Graph<int> g(n);
    rep(i, n)rep(j, n){
        int a;
        scanf("%d", &a);
        if(a >= 0) g.add_edge(i, j, a);
    }
    printf("%d\n", g.kruskal());
}

C++: #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
struct Node{
	int f,e,w;
};
inline bool cmp(Node a,Node b){
	return a.w<b.w;
}
int bc[100+30];
int bcj(int x){
    if(bc[x]==x) return bc[x];
    return bc[x]=bcj(bc[x]);
}
int ans,n;
vector<Node> edl;
int main(){
	cin>>n;
	for(int i=0;i<n;++i) bc[i]=i;
	for(int i=0;i<n;++i){
		for(int j=0;j<n;++j){
			Node x;
			x.f=i;x.e=j;
			cin>>x.w;
			if(x.w!=-1) edl.push_back(x);
		}
	}
	sort(edl.begin(),edl.end(),cmp);
	int tot=0,xi=0;
	while(tot<n-1){
		int a=edl[xi].f,b=edl[xi].e;
		if(bc[bcj(a)]!=bcj(b)){
			bc[bcj(a)]=bcj(b);
			++tot;
			ans+=edl[xi].w;
		}
		++xi;
	}
	cout<<ans<<endl;
	return 0;
}

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;
int M[MAX][MAX];

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

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

  d[0] = 0;

  while(1)
    {
      minv = INFTY;

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

  return sum;

}


int main()
{
  int e;
  int i,j;
  
 cin >>n;

  for(i = 0; i < n;i++)
    {
      for(j = 0; j < n; j++)
	{
	 
	  cin >> e;
	 M[i][j] = (e == -1) ? INFTY : e;
        }
    }

 cout << prim() << endl;
  return 0;
  
}

C++: #include <bits/stdc++.h>
using namespace std;

#define INF INT32_MAX

int main()
{
	int n;
	cin >> n;
	vector<vector<int>> cost( n, vector<int>( n ) );
	for( int i = 0; i < n; i++ ) {
		for( int j = 0; j < n; j++ ) {
			int c;
			cin >> c;
			cost[i][j] = INF;
			if( c >= 0 ) cost[i][j] = c;
		}
	}

	vector<int> mincost( n, INF );
	vector<int> used( n );
	mincost[0] = 0;
	int ans = 0;
	while( true ) {
		int v = -1;
		for( int u = 0; u < n; u++ ) {
			if( used[u] == 0 && ( v < 0 || mincost[u] < mincost[v] ) ) v = u;
		}
		if( v < 0 ) break;
		used[v] = 1;
		ans += mincost[v];
		for( int u = 0; u < n; u++ ) {
			mincost[u] = min( mincost[u], cost[v][u] );
		}
	}

	cout << ans << endl;
}

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

using namespace std;

#define REP(var, count) for(int var=0; var<count; var++)

struct unionf {
	
	vector<int> data;
	
	unionf(int n) {
		REP(i, n+1) { data.push_back(i); }
	}
	
	int root(int a) {
		if(data[a] == a) { return a; }
		return (data[a] = root(data[a]));
	}
	
	bool issame(int a, int b) {
		return root(a) == root(b);
	}
	
	void unite(int a, int b) {
		data[root(a)] = root(b);
	}

};

int main(void) {
	int N;
	cin >> N;
	
	vector<pair<int, pair<int, int> > > edge;
	
	REP(x, N) {
		REP(y, N) {
			int c;
			cin >> c;
			if ( x <= y ) { continue; }
			if ( c == -1 ) { continue; }
			edge.push_back( make_pair(c, make_pair(x,y)) );
		}
	}
	
	sort(edge.begin(), edge.end());
	
	unionf uf(N);
	
	int cnt = 0;
	int ret = 0;
	
	REP(i, edge.size() ) {
		
		pair<int, int> sd = edge[i].second;
		if ( ! uf.issame( sd.first, sd.second ) ) {
			cnt ++;
			ret += edge[i].first;
			uf.unite(sd.first, sd.second);
			//cout << "joint " << sd.first << " " << sd.second << " -> " << edge[i].first << endl;
		}
		
		if ( cnt == N-1 ) { break; }
	}
	
	cout << ret << endl;
}