Go: package main

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

func getScanner(fp *os.File) *bufio.Scanner {
	scanner := bufio.NewScanner(fp)
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 500001), 500000)
	return scanner
}

func getNextString(scanner *bufio.Scanner) string {
	scanner.Scan()
	return scanner.Text()
}

func getNextInt(scanner *bufio.Scanner) int {
	i, _ := strconv.Atoi(getNextString(scanner))
	return i
}

func main() {
	fp := os.Stdin
	if len(os.Args) > 1 {
		fp, _ = os.Open(os.Args[1])
	}

	scanner := getScanner(fp)
	writer := bufio.NewWriter(os.Stdout)

	n := getNextInt(scanner)

	g := make([][]int, n)
	ans := make([][]int, n)

	inf := 1 << 30
	for i := 0; i < n; i++ {
		g[i] = make([]int, n)
		ans[i] = make([]int, n)
		for ii := 0; ii < n; ii++ {
			g[i][ii] = getNextInt(scanner)
			if g[i][ii] == -1 {
				g[i][ii] = inf
			}
			ans[i][ii] = -1
		}
	}

	im := make(IntMap, 1)

	im.increment(1)

	for len(im) < n {
		min := inf
		u := -1
		v := -1
		for i := range im {
			for ii := 0; ii < n; ii++ {
				if im.get(ii) != 0 {
					continue
				}
				if min > g[i][ii] {
					min = g[i][ii]
					u = i
					v = ii
				}
			}
		}
		im.increment(v)
		ans[u][v] = min
		ans[v][u] = min
	}

	sum := 0
	for i := 0; i < n-1; i++ {
		for ii := i + 1; ii < n; ii++ {
			if ans[i][ii] != -1 {
				sum += ans[i][ii]
			}
		}
	}

	fmt.Fprintln(writer, sum)
	writer.Flush()
}

// IntMap ...
type IntMap map[int]int

func (m IntMap) get(key int) int {
	if _, ok := m[key]; ok {
		return m[key]
	}
	return 0
}
func (m IntMap) increment(key int) {
	if _, ok := m[key]; ok == false {
		m[key] = 0
	}
	m[key]++
}

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

#define INF 2000

int n;
int cost[110][110], mincost[110];
bool used[110];

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

int main(){
  
  cin >> n;
  for(int i = 0;i < n;i++){
    for(int j = 0;j < n;j++){
      cin >> cost[i][j];
      if(cost[i][j] == -1) cost[i][j] = INF;
    }
  }
  
  cout << prim() << endl;
  
  return 0;
}

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

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

void init(int N) { // Initially all the points are individualized
  for (int i=0; i<=N; ++i) P[i] = i;
}

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;
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++: /*
 * a.cc: 
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>

using namespace std;

/* constant */

const int MAX_N = 100;

/* typedef */

struct Edge {
  int i, j, c;
  Edge() {}
  Edge(int _i, int _j, int _c): i(_i), j(_j), c(_c) {}
  bool operator<(const Edge &e) const { return c < e.c; }
};

typedef vector<Edge> ve;

struct UFT {
  int links[MAX_N], ranks[MAX_N], sizes[MAX_N];

  void clear(int n) {
    for (int i = 0; i < n; i++) links[i] = i, ranks[i] = sizes[i] = 1;
  }
  UFT() {}
  UFT(int n) { clear(n); }

  int root(int i) {
    int i0 = i;
    while (links[i0] != i0) i0 = links[i0];
    return (links[i] = i0);
  }

  int rank(int i) { return ranks[root(i)]; }
  int size(int i) { return sizes[root(i)]; }
  bool same(int i, int j) { return root(i) == root(j); }

  int merge(int i0, int i1) {
    int r0 = root(i0), r1 = root(i1), mr;
    if (r0 == r1) return r0;
    if (ranks[r0] == ranks[r1]) {
      links[r1] = r0;
      sizes[r0] += sizes[r1];
      ranks[r0]++;
      mr = r0;
    }
    else if (ranks[r0] > ranks[r1]) {
      links[r1] = r0;
      sizes[r0] += sizes[r1];
      mr = r0;
    }
    else {
      links[r0] = r1;
      sizes[r1] += sizes[r0];
      mr = r1;
    }
    return mr;
  }
};

/* global variables */

/* subroutines */

/* main */

int main() {
  int n;
  cin >> n;

  ve es;

  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) {
      int ai;
      cin >> ai;
      if (ai >= 0) es.push_back(Edge(i, j, ai));
    }
  sort(es.begin(), es.end());

  UFT uft(n);
  int en = es.size(), sum = 0;

  for (int i = 0; i < en; i++) {
    Edge &ei = es[i];
    if (! uft.same(ei.i, ei.j)) {
      uft.merge(ei.i, ei.j);
      sum += ei.c;
    }
  }

  printf("%d\n", sum);
  return 0;
}