Go: package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"os"
	"strconv"
)

type Node struct {
	id     int
	weight int
}

func init() {
	sc.Split(bufio.ScanWords)
}

type NodeHeap []Node

func (h NodeHeap) Len() int           { return len(h) }
func (h NodeHeap) Less(i, j int) bool { return h[i].weight < h[j].weight }
func (h NodeHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

func (h *NodeHeap) Push(x interface{}) {
	*h = append(*h, x.(Node))
}

func (h *NodeHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

var sc = bufio.NewScanner(os.Stdin)

func scanInt() int {
	num, _ := strconv.Atoi(scanString())
	return num
}

func scanString() string {
	sc.Scan()
	return sc.Text()
}

func init() {
	sc.Split(bufio.ScanWords)
}

func main() {
	n := scanInt()

	list := make([][]int, n)
	seen := make([]bool, n)
	for i := range list {
		list[i] = make([]int, n)
		for j := range list[i] {
			list[i][j] = scanInt()
		}
	}

	start := Node{id: 0, weight: 0}
	h := &NodeHeap{start}
	heap.Init(h)

	sum := 0
	for h.Len() > 0 {
		node := heap.Pop(h).(Node)
		if seen[node.id] {
			continue
		}
		seen[node.id] = true
		sum += node.weight

		for i, w := range list[node.id] {
			if w < 0 {
				continue
			}
			heap.Push(h, Node{id: i, weight: w})
		}
	}

	fmt.Println(sum)
}

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;
}