Go: package main

import (
	"bufio"
	"fmt"
	"log"
	"math"
	"os"
	"strconv"
	"strings"
)

type color int

const (
	white color = iota // 未訪問
	mst                // MSTとして確定
)

// 頂点
type node struct {
	matrix   []int // 隣接行列
	minToMst int   // MSTへの重み最小値
	parent   int   // 最小値の相手
	color    color
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	n := eGetInt(scanner)

	nodes := make([]node, n)
	for i := 0; i < n; i++ {
		nodes[i].matrix = eAtoi((strings.Fields(eGetline(scanner))))
		nodes[i].parent = -1
		nodes[i].minToMst = math.MaxInt16
		nodes[i].color = white
	}

	// 初回はnode[0]がMSTに入るように,minToMstを設定
	nodes[0].minToMst = 0
	for { // 全部チェックするまで

		// どの頂点を新たにMSTに取り込むか
		min := math.MaxInt16
		u := -1
		for i := 0; i < n; i++ {
			if nodes[i].color == mst {
				continue
			}
			if nodes[i].minToMst < min {
				u = i
				min = nodes[i].minToMst
			}
		}

		if u == -1 {
			break
		}
		// MSTに追加する頂点決定
		nodes[u].color = mst

		// MSTに属していない頂点それぞれについて,MSTとの最小の重みを更新
		for i := 0; i < n; i++ {
			if nodes[i].color == mst {
				continue
			}
			if nodes[i].matrix[u] == -1 {
				// 接してない
				continue
			}
			if nodes[i].matrix[u] < nodes[i].minToMst {
				// node[u]との重みが最小
				nodes[i].minToMst = nodes[i].matrix[u]
				nodes[i].parent = u
			}
		}
	}

	sum := 0
	for _, v := range nodes {
		// node[0]はparentが入っていない
		if v.parent != -1 {
			sum += v.matrix[v.parent]
		}
	}
	fmt.Println(sum)
}

func eGetInt(scanner *bufio.Scanner) int {
	t := eAtoi(strings.Fields(eGetline(scanner)))
	return t[0]
}

func eGetline(p *bufio.Scanner) string {
	if !p.Scan() {
		if err := p.Err(); err != nil {
			log.Fatal(err.Error())
		}
		return ""
	}
	return p.Text()
}

func eAtoi(s []string) []int {
	ints := make([]int, len(s))
	var err error
	for i, e := range s {
		ints[i], err = strconv.Atoi(e)
		if err != nil {
			log.Fatal(err.Error())
		}
	}
	return ints
}

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

const int MAX = 100;
const int INFINITY = 2 << 21;
int n;
int G[MAX][MAX];
int distances[MAX];
int parents[MAX];
int states[MAX];

int prim() {
  int id = 0;
  distances[id] = 0;

  while (1) {
    int min = INFINITY;

    for (int i = 0; i < n; i++) {
      if (states[i] == 0 && distances[i] < min) {
        min = distances[i];
        id = i;
      }
    }

    if (min == INFINITY) break;

    for (int i = 0; i < n; i++) {
      if (states[i] != 0 || G[id][i] == -1) continue;
      if (G[id][i] < distances[i]) {
        distances[i] = G[id][i];
        parents[i] = id;
      }
    }

    states[id] = 1;
  }

  int sum = 0;
  for (int i = 0; i < n; i++) {
    if (parents[i] != -1) sum += distances[i];
  }
  return sum;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  cin >> n;

  for (int i = 0; i < n; i++) {
    distances[i] = INFINITY;
    parents[i] = -1;
    states[i] = 0;
    for (int j = 0; j < n; j++) {
      cin >> G[i][j];
    }
  }

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

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

int n;
int a[101][101];
int flg[101];
int t[101];
int sum = 0;

void visit(){
  int ima = 0;
  int mine = 100000000;
  
  
  for(int k=0;k<n-1;k++) {
    mine = 10000000;
    for(int i=0;i<n;i++) {
      if(flg[i] == 0 && mine > t[i]) {
	mine = t[i];
	ima = i;
      }
    }
    sum += mine;
    flg[ima] = 1;
    
    for(int i=0;i<n;i++) 
      if(a[ima][i] != -1) 
	if(t[i] > a[ima][i] ) t[i] = a[ima][i];
    
    
  }
}

int main() {

  cin >> n;

  for(int i=0;i<n;i++) 
    for(int j=0;j<n;j++) 
      cin >> a[i][j];
  
  for(int i=0;i<n;i++) {
    flg[i] = 0;
    t[i] = 100000000;
  }
  
  t[0] = 0;
  flg[0] = 1;
  for(int i=0;i<n;i++) 
    if(a[0][i] != -1) t[i] = a[0][i];

  visit();

  cout << sum << endl;
 
  return 0; 
  
}

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

int n;
int g[101][101];

int d[101];
char c[101];
int p[101];

void prim() {
    for (int i = 0; i < n; ++i) {
        d[i] = INT_MAX;
        c[i] = 'w';
    }
    c[0] = 'b';
    d[0] = 0;
    while (true) {
        int u, v;
        int mine = INT_MAX;
        for (int j = 0; j < n; ++j) {
            if (c[j] == 'b') {
                u = j;
                for (int k = 0; k < n; ++k) {
                    if(g[u][k] > -1 && g[u][k] <= d[k] && c[k] != 'b' && g[u][k] <= mine) {
                        d[k] = g[u][k];
                        mine = d[k];
                        v = k;
                    }
                }
            }
        }
        p[v] = u;
        c[v] = 'b';
        if(mine == INT_MAX) break;
    }
}

int main() {
    cin >> n;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            int w;
            cin >> w;
            g[i][j] = w;
        }
    }
    prim();
    int sum;
    for (int k = 0; k < n; ++k) {
        sum += d[k];
    }
    cout << sum << endl;


    return 0;
}

C++: #include <iostream>
#include <string>
#include <vector>
#include <cstring>
#include <climits>
#include <algorithm>
#include <map>

using namespace std;

struct edge {
    int from, to, cost;
};

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

    vector<edge> E;
    int cost;
    for (int i=0; i<n; ++i) {
        for (int j=0; j<n; ++j) {
            cin >> cost;
            if (0 <= cost) {
                E.push_back((edge){ i, j, cost });
            }
        }
    }

    bool used[100] = {};
    used[0] = true;

    int ret = 0;

    while (1) {
        int next = -1;
        int min_cost = INT_MAX;
        for (int i=0; i<(int)E.size(); ++i) {
            edge &e = E[i];
            if (used[e.from] && ! used[e.to] && e.cost < min_cost) {
                next = e.to;
                min_cost = e.cost;
            }
        }
        if (next == -1) break;
        used[next] = true;
        ret += min_cost;
    }

    cout << ret << endl;

    return 0;
}

C++: #include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
using namespace std;
#define NIL -2000000001
#define INFTY 2000000001
#define MAX 101
#define WHITE 0
#define GRAY 1
#define BLACK 2

int n = 0;
int adm[MAX][MAX];
int color[MAX];
int d[MAX], p[MAX];
queue<int> queueBfs;


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

  while (true) {
    int mincost = INFTY;
    int u; //訪問する頂点

    for (int i = 0; i < n; i++) {
      if (color[i] != BLACK && d[i] < mincost) {
        mincost = d[i];
        u = i;
      }
    }
    if (mincost == INFTY) break;
    sum += mincost;
    color[u] = BLACK;

    // u周りの頂点vの情報を入れる
    for (int v = 0; v < n; v++) {
      if (color[v] != BLACK && adm[u][v] != -1 && adm[u][v] < d[v]) {
        d[v] = adm[u][v];
        p[v] = u;
        color[v] = GRAY;
      }
    }
  }

  return sum;
}

int main() {
  scanf("%d", &n);
  for ( int i = 0; i < n; i++ ) {
    for ( int j = 0; j < n; j++) {
      scanf("%d", &adm[i][j]);
    }
  }

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

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

int n,m=0,tmp,p[110],ans=0,a,b,c; //m:辺の数
tuple<int,int,int> line[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;}
    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(){
    cin>>n;
    init(n);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>tmp;
            if(j>i){
                if(tmp!=-1){
                    line[m]=make_tuple(tmp,i,j);
                    m++;
                }
            }
        }
    }
    sort(line,line+m);
    init(n);
    for(int i=0;i<m;i++){
        c=get<0>(line[i]);
        a=get<1>(line[i]);
        b=get<2>(line[i]);
        if(!(is_same_set(a,b))){
            unite(a,b);
            ans+=c;
        }
        //cout<<c<<a<<b<<endl;
    }
    cout<<ans<<endl;
}