Go: package main

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

const BIG_COST = 3000

const (
	ST_NOT_YET = iota
	ST_JOINED
)

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)

	nNodes := scanInt(sc)
	costs := make([][]int, nNodes)

	for r := 0; r < nNodes; r++ {
		costs[r] = make([]int, nNodes)
		for c := 0; c < nNodes; c++ {
			costs[r][c] = scanInt(sc)
		}
	}

	states := make([]int, nNodes)
	minCosts := make([]int, nNodes)

	for i := 1; i < nNodes; i++ {
		minCosts[i] = BIG_COST
	}

	for {
		var u int
		minCost := BIG_COST

		for i := 0; i < nNodes; i++ {
			if states[i] != ST_JOINED && minCosts[i] < minCost {
				minCost = minCosts[i]
				u = i
			}
		}

		// 全てのノードが MST に JOIN できたので終了。
		if minCost == BIG_COST {
			break
		}

		states[u] = ST_JOINED

		for v := 0; v < nNodes; v++ {
			cost := costs[u][v]

			// MST内の u と MST外の v との辺の重みをそれぞれ minCosts[v] として
			// 保存しておく。このうち辺の重みが最小となる v が次のループで MST に JOIN する。
			if states[v] != ST_JOINED && cost != -1 && cost < minCosts[v] {
				minCosts[v] = cost
			}
		}
	}

	sum := 0
	for _, cost := range minCosts {
		sum += cost
	}
	fmt.Println(sum)
}

func scanInt(sc *bufio.Scanner) int {
	sc.Scan()
	v, _ := strconv.Atoi(sc.Text())
	return v
}

C++: #include<iostream>
using namespace std;
static const int INF =1000000;
static const int WHITE =0;
static const int GRAY =1;
static const int BLACK =2;
static const int N =100;

int n,A[N][N];

int d[N],p[N],color[N];

int prim(){
  //初期化
   for(int i =0;i<n;i++){
     color[i] =WHITE;
     d[i] = INF;
   }
  int mincost,u;
   d[0]=0;
   p[0]=-1;

   int sum =0;

   while(1){
     int mincost = INF;
     for (int i =0;i<n;i++){
       if(color[i]!=BLACK && d[i] < mincost){
         mincost = d[i];
         u =i;
       }
     }
     if(mincost == INF) break;
     sum += mincost;
     color[u] = BLACK;
     for(int j =0;j<n;j++){
       if(color[j] != BLACK && A[u][j] != INF){
         if(A[u][j] < d[j]){
           d[j] =A[u][j];
           p[j] =u;
           color[j] = GRAY;
         }
       }
     }
   }
   return sum;
}

int main(){
  cin >> n;

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

  return 0;
}

C++: // J4180449 三宅亮輔
// 問題名
// - Disjoint Set
// 問題URL
// - https://onlinejudge.u-aizu.ac.jp/problems/DSL_1_A
// 所要時間
// - 30分
// 学んだこと
//  Union Find木の実装方法
//  蟻本を読んでroot関数にparの値を追加することが有効であると理解した。
//  アッカーマン関数の逆関数のオーダーになることがわかった。

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

typedef long long ll;
typedef pair<int, int> P;

vector<P> v;
int n, q;

int par[100];

int root(int a) {
    if(a == par[a])
        return a;
    return par[a] = root(par[a]);
}

bool same(int a, int b) { return root(a) == root(b); }

void unite(int a, int b) {
    a = root(a);
    b = root(b);
    par[a] = b;
}

int main() {
    int ans = 0;
    cin >> n;
    for(int i = 0; i < n; i++)
        par[i] = i;

    for(int i = 0; i < n * n; i++) {
        int a;
        cin >> a;
        v.push_back(P(a, i));
    }
    sort(v.begin(), v.end());

    for(int i = 0; i < n * n; i++) {
        if(v[i].first != -1) {
            int x = v[i].second % n;
            int y = v[i].second / n;
            if(!same(x, y)) {
                unite(x, y);
                ans += v[i].first;
            }
        }
    }

    cout << ans << endl;
}

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

int main(void)
{
	int n, now = 0, flag[101] = {};
	long ans = 0, an[100][100], min[100];

	cin >> n;

	for(int i = 0; i < n; i++) {
		for(int j = 0; j < n; j++)
			cin >> an[i][j];
		min[i] = LONG_MAX;
	}

	do {
		long key = LONG_MAX, key_i;
		flag[now] = 1;
		flag[100] = 0;

		for(int i = 0; i < n; i++) {
			if(an[now][i] != -1 && an[now][i] < min[i] && flag[i] == 0)
				min[i] = an[now][i];
			if(flag[i] == 0 && min[i] < key) {
				key = min[i];
				key_i = i;
			}
			if(flag[i] == 1)
				flag[100]++;
		}

		now = key_i;
		ans += key;

	}while(flag[100] != n - 1);

	cout << ans << endl;

	return 0;
}

C++: #if 0
AOJ??????accepted??????????????????
???????????????60??????????????§?????????

pair???????????????????????¨
????????¨?????????pair?????????????????????????????¨?????????????????????????????????
#endif

#include <iostream>
#include <algorithm>
#include <utility>
using namespace std;

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

int root(int a){//a???root????±???????
  if(P[a]==a)
    return a;
  return (P[a]=root(P[a]));
}

bool is_same_set(int a,int b){//??????set?????????
  return root(a)==root(b);
}

void unite(int a,int b){
  P[root(a)]=root(b);
}

int main(){
  int N;
  cin>>N;
  int A[N][N];
  
  for(int i=0; i<N;i++){//????????????
    for(int j=0;j<N;j++){
      cin>>A[j][i];
    }
  }

  int M = 0; // ????????????????????°
  int num=N*N;
  int cost[num];
  int src[num],dst[num];
  for (int r=0; r<N;r++){
    for (int c=0; c<r;c++){
      if (A[r][c] > -1) {
	cost[M] = A[r][c];
	src[M] = r;
	dst[M] = c;
	M += 1;
      }
    }
  }

  pair<int,int> edge[100000+10];//?§??????????????????¢????????????
  for(int i=0; i<M;i++){
    edge[i]=make_pair(cost[i],i);
  }
  sort(edge,edge+M);

  int edges[M][3];
  for(int i=0; i<M;i++){//?????????????????????
    edges[i][0]=edge[i].first;
    edges[i][1]=src[edge[i].second];
    edges[i][2]=dst[edge[i].second];
  }
  /*
  check!
  for(int i=0; i<M;i++){
    cout<<"news cost="<<edges[i][0]<<" ,"<<edges[i][1]<<"-"<<edges[i][2]<<endl;
  }
  */




  init(N);
  int sum=0;
  for(int i=0; i<M;i++){//???????????????????????????
    if(is_same_set(edges[i][1],edges[i][2])==0){
      unite(edges[i][1],edges[i][2]);
      sum=sum+edges[i][0];
    }
  }
    cout<<sum<<endl;
}