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>
#include <vector>
#include <algorithm>
#include <queue>
#include <functional>

using namespace std;
typedef pair<int, int> P;   //cost, to
static const int INF = 1e9;
static const int SIZE = 101;
int par[SIZE];
int rk[SIZE];
int d[SIZE];
int n;

struct edge
{
	int u, v, cost;
};

struct edge2
{
	int to, cost;
};

bool comp(const edge& e1, const edge& e2)
{
	return(e1.cost < e2.cost);
}

void init()
{
	for (int i = 0; i < SIZE; ++i)
	{
		par[i] = i;
		rk[i] = 0;
	}
}

int find(int x)
{
	if (x == par[x])
	{
		return(x);
	}
	else
	{
		return(par[x] = find(par[x]));
	}
}

void unite(int a, int b)
{
	int x = find(a);
	int y = find(b);
	if (x == y)
	{
		return;
	}
	if (rk[x] < rk[y])
	{
		par[x] = y;
	}
	else
	{
		par[y] = x;
		if (rk[x] == rk[y])
		{
			++rk[x];
		}
	}
}

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

int kruskal(vector<edge>& es)
{
	init();
	int res = 0;
	sort(es.begin(), es.end(), comp);
	for (int i = 0; i < es.size(); ++i)
	{
		edge e = es[i];
		if (!same(e.u, e.v))
		{
			unite(e.u, e.v);
			res += e.cost;
		}
	}
	return(res);
}

int prim(vector<edge2>* G)
{
	vector<bool> isUsed(n);
	for (int i = 0; i < n; ++i)
	{
		isUsed[i] = false;
	}
	priority_queue<P, vector<P>, greater<P> > pque;
	P p = make_pair(0, 0);
	pque.push(p);
	int res = 0;
	while (!pque.empty())
	{
		P p = pque.top();
		pque.pop();
		int v = p.second;
		if (isUsed[v])
		{
			continue;
		}
		isUsed[v] = true;
		res += p.first;
		for (int i = 0; i < G[v].size(); ++i)
		{
			edge2 e = G[v][i];
			pque.push(P(e.cost, e.to));
		}
	}
	return(res);
}


void solve()
{
	cin >> n;

// For Kruskal
	//vector<edge> es;
	//for (int i = 0; i < n; ++i)
	//{
	//	for (int j = 0; j < n; ++j)
	//	{
	//		int cost;
	//		cin >> cost;
	//		if (cost != -1)
	//		{
	//			edge e;
	//			e.u = i;
	//			e.v = j;
	//			e.cost = cost;
	//			es.push_back(e);
	//		}
	//	}
	//}
	//cout << kruskal(es) << endl;

// For Prim
	vector<edge2> G[SIZE];
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			int cost;
			cin >> cost;
			if (j >= i && cost != -1)
			{
				edge2 e1, e2;
				e1.to = j;
				e1.cost = cost;
				e2.to = i;
				e2.cost = cost;
				G[i].push_back(e1);
				G[j].push_back(e2);
			}
		}
	}
	cout << prim(G) << endl;
}

int main()
{
	solve();
	return(0);
}

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

int main()
{
    int n,tmp,sum=0,MIN;
    int d[105],v[105],m[105][105],p,child;
    cin>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++)cin>>tmp,m[i][j]=tmp;
        v[i]=0;
    }
    vector<int>G;
    v[0]=1;
    G.push_back(0);
    for(int M=1;M<n;M++)
    {
        MIN=2005;
        for(int i=0;i<M;i++)
            for(int j=0;j<n;j++)
                if(m[G[i]][j]!=-1&&!v[j]&&m[G[i]][j]<MIN)
                {
                    MIN=m[G[i]][j];
                    p=G[i];
                    child=j;
                }
        G.push_back(child);
        sum+=m[p][child];
        v[child]=1;
    }
    cout<<sum<<endl;
    return 0;
}

C++: #include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <queue>
#include <stack>
#include <math.h>

#define ll long long
#define Int int
#define loop(x, start, end) for(Int x = start; x < end; x++)
#define loopdown(x, start, end) for(int x = start; x > end; x--)

using namespace std;

#define MAX_N 100
#define MAX_INT (1 << 21)


Int prim(Int W[MAX_N][MAX_N], Int n) {
  Int parent[n], key[n];
  bool mst_set[n];
  
  loop(i,0,n) key[i] = MAX_INT, mst_set[i] = false;
  
  key[0] = 0, parent[0] = -1;
  
  // why n-1 ?
  loop(count,0,n-1) {
      Int u = -1;
      Int min_ = MAX_INT;
      loop(v,0,n) {
          if (mst_set[v] == false && key[v] < min_) {
              min_ = key[v], u = v;
          }
      }
      
      mst_set[u] = true;
      
      loop(v,0,n) {
          if (W[u][v] != MAX_INT && mst_set[v] == false && W[u][v] < key[v]) {
              parent[v] = u, key[v] = W[u][v];
          }
      }
  }

  Int sum = 0;
  loop(v,1,n) {
    sum += W[v][parent[v]];
  }

  return sum;
}


int main(void) {
  Int n, w;
  Int W[MAX_N][MAX_N];
  cin >> n;
  loop(x,0,n) {
    loop(y,0,n) {
      cin >> w;
      W[x][y] = W[y][x] = (w == -1) ? MAX_INT : w;
    }
  }

  cout << prim(W, n) << endl;
}