Go: package main

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

const (
	WHITE int = iota
	GRAY
	BLACK
)

type graph struct {
	G [][]int
	C []int
	D []int
	P []int
}

var INFTY = 1 << 32

func constructGraph() *graph {
	sc := bufio.NewScanner(os.Stdin)
	sc.Scan()
	n, _ := strconv.Atoi(sc.Text())

	g := make([][]int, n)
	c := make([]int, n)
	d := make([]int, n)
	p := make([]int, n)

	for i := 0; i < n; i++ {
		sc.Scan()
		fields := strings.Fields(sc.Text())
		g[i] = toIntSlice(fields)
	}

	return &graph{g, c, d, p}
}

func (g *graph) initMst() {
	for i := 0; i < len(g.G); i++ {
		g.C[i] = WHITE
		g.D[i] = INFTY
	}
	g.D[0] = 0
	g.P[0] = -1
}

func (g *graph) primMst() int {
	g.initMst()

	var u int
	for {
		mincost := INFTY
		for i := 0; i < len(g.G); i++ {
			if g.C[i] != BLACK && g.D[i] < mincost {
				mincost = g.D[i]
				u = i
			}
		}

		if mincost == INFTY {
			break
		}

		g.C[u] = BLACK

		for i := 0; i < len(g.G); i++ {
			if g.C[i] != BLACK && g.existEdge(u, i) {
				if g.G[u][i] < g.D[i] {
					g.D[i] = g.G[u][i]
					g.P[i] = u
				}
			}
		}
	}

	totalCost := 0
	for _, cost := range g.D {
		totalCost += cost
	}
	return totalCost
}

func (g *graph) existEdge(u, v int) bool {
	return g.G[u][v] != INFTY && g.G[v][u] != INFTY
}

func toIntSlice(s []string) []int {
	a := make([]int, len(s))
	for i, v := range s {
		num, _ := strconv.Atoi(v)
		if num == -1 {
			num = INFTY
		}
		a[i] = num
	}
	return a
}

func main() {
	g := constructGraph()
	fmt.Println(g.primMst())
}

C++: #include <iostream>
#include <queue>

using namespace std;




struct link { //link connecting x and y vertices
  int x;
  int y;
  int weight;
  bool operator<(const link& other) const
  {
    return weight > other.weight; // for min priority queue, trick the operator
  }
};

priority_queue<link> links;
int roots[100];

int root(int x) {
  if (x == roots[x]) {
    return x;
  } else {
    //roots[x] = root(roots[x]); //attach all to root
    return root(roots[x]);
  }
}

bool same(int x, int y) {
  return (root(x) == root(y));
}

void unite(int x, int y) {
  roots[root(x)] = root(y);
}


  
int main() {
  int min_cost = 0;
  int n;
  cin >> n;


  for (int i = 0; i < n; i++) {
    roots[i] = i; // initialize roots
    for (int j = 0; j < n; j++) {
      
      int weight;
      cin >> weight;
      if (j <= i ) continue;
      if (weight != -1) {
	link new_link = {i, j, weight};
	links.push(new_link);
	//cout << "link added has i j weight: " << i << " " << j << " " << weight << endl;
      }
    }
  }

  while (!links.empty()) {
    link cur_link = links.top();
    //cout << "cur link weight: " << cur_link.weight << " x: " << cur_link.x << " y: " << cur_link.y << endl;
    if (!same(cur_link.x, cur_link.y)) {
      min_cost += cur_link.weight;
      unite(cur_link.x, cur_link.y);
    }
    links.pop();
  }

  cout << min_cost << endl;
      
    
}

C++: #include<iostream>
using namespace std;
#define MAX 100
#define White 1
#define Black 2
#define Red 3
#define Infinit 2001
struct Vertex {
	int weight,color,parent;
};
int M[MAX][MAX];
int n;
Vertex v[MAX];
void search() {
	int weight[MAX],pointer,min;
	for (int i = 0; i < n; i++) {
		if (i == 0) {
			v[i].weight = 0;
		}
		else {
			v[i].weight = Infinit;
		}
		v[i].color = White;
		v[i].parent = -1;
	}
	while (true) {
		min = Infinit;
		pointer = -1;
		for (int i = 0; i < n; i++) {
			if (v[i].color != Black && min>v[i].weight) {
					min = v[i].weight;
					pointer = i;
			}
		}
		if (min==Infinit) break;
		v[pointer].color = Black;
		for (int k = 0; k < n; k++) {
			if (M[pointer][k] != -1 && v[k].color!=Black) {
				if (M[pointer][k]<v[k].weight) {
					v[k].weight = M[pointer][k];
					v[k].parent = pointer;
					v[k].color = Red;
				}
			}
		}

	}
	int sum = 0;
	for (int i = 0; i < n; i++) {
		sum += v[i].weight;
	}
	cout << sum << endl;


}
int main() {
	int id;
	cin >> n;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >>id;
			M[i][j]=id;
		}
	}
	search();
}

C++: #include <iostream>
#include <algorithm>
#define N 100
#define INF 2000000000
#define WHITE 0
#define GRAY 1
#define BLACK 2
using namespace std;

int n;
int M[N][N],color[N],d[N],p[N];
   //M??????????????????color????¨??????¶???(0,1,2),d????????????????°???????????¨????
   //p???MST???????°???¨?????¨??????????????????????????????

void Prim() {
	for (int i = 0;i < n;i++) d[i] = INF;
	d[0] = 0;  //?????????????????????????????§???????????§????´???????????????????????????????
	/*p[0] = -1;  //??????????????????????????????????????????*/

	int u;
	while (true) {
		int min = INF;
		for (int i = 0;i < n;i++) {
			if(color[i]!=BLACK&&min>d[i]){
				min = d[i];
				u = i;
			}
		}

	if (min == INF) break;

	color[u] = BLACK;

	for (int v = 0;v < n;v++) 
		if(color[v]!=BLACK&&M[u][v]!=-1)
			if (M[u][v] < d[v]) {
				d[v] = M[u][v];
				/*p[v] = u;*/
				/*color[v] = GRAY;*/
			}

	}

	int sum = 0;
	for (int i = 0;i < n;i++) sum += d[i];
	cout << sum << endl;
		
}

int main() {
	cin >> n;
	for (int i = 0;i < n;i++)
		for (int j = 0;j < n;j++) {
			cin >> M[i][j];
			if (M[i][j] == -1) M[i][j] = INF;
		}

	Prim();

}

C++: #include "bits/stdc++.h"
#include <unordered_set>

#define _CRT_SECURE_NO_WARNINGS

#define REP(i, n) for(decltype(n) i = 0; i < (n); i++)
#define REP2(i, x, n) for(decltype(x) i = (x); i < (n); i++)
#define REP3(i, x, n) for(decltype(x) i = (x); i <= (n); i++)
#define RREP(i, n) for (decltype(n) i = (n) - 1; i >= 0; i--)

#define ALL(a) (a).begin(),(a).end()
#define SORT(c) sort((c).begin(),(c).end())
#define DESCSORT(c) sort(c.begin(), c.end(), greater<int>())

using namespace std;

const int INF = 1000000000;
const double PI = 3.1415926535897932384626433832795;

// N, E, S, W
const int dx[4] = { 1, 0, -1, 0};
const int dy[4] = { 0, 1, 0, -1};

using LL = long long int;
using LD = long double;
using pii = pair<int, int>;
using pll = pair<LL, LL>;
using pdd = pair<double, double>;
using vi = vector<int>;
using vl = vector<LL>;
using vd = vector<double>;
using vs = vector<string>;
using vvi = vector<vi>;

//==============================================
int n;
vi color, D, P;
vvi M;

int solve() {
	D[0] = 0;

	int u, minV;
	while (true) {
		u = -1;
		minV = INF;
		REP(i, n) {
			if (color[i] != 2 && D[i] < minV) {
				u = i;
				minV = D[i];
			}
		}

		if (u == -1) break;
		color[u] = 2;

		REP(i, n) {
			if (color[i] != 2 && M[u][i] != INF && D[i] > M[u][i]) {
				D[i] = M[u][i];
				P[i] = u;
				color[i] == 1;
			}
		}
	}

	int sum = 0;
	REP(i, n) {
		if (P[i] != -1) {
			sum += M[i][P[i]];
		}
	}

	return sum;
}

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

	cin >> n;

	color.resize(n);
	D.resize(n, INF);
	P.resize(n, -1);
	M.resize(n, vi(n, INF));

	int edge;
	REP(i, n) {
		REP(j, n) {
			cin >> edge;
			M[i][j] = (edge == -1 ? INF : edge);
		}
	}

	cout << solve() << "\n";
	return 0;
}

C++: #include<iostream>
#include<vector>

int main() {
	int num;
	std::cin >> num;

	std::vector<std::vector<int> > v(num);

	for (int i = 0; i < num; i++) {
		for (int j = 0; j < num; j++) {
			int n;
			std::cin >> n;
			v[i].push_back(n);
		}
	}

	std::vector<int> n(v.size(), 0);
	int count = 0;
	for (int i = 1; i <= 2000; i++) {
		for (size_t j = 0; j < v.size(); j++) {
			for (size_t k = 0; k < v.size(); k++) {
				if (v[j][k] == i && (n[j] == 0 || n[k] == 0)) {
					n[j] = n[k] = 1;
					count += i;
				}
			}
		}
	}

	std::cout << count << std::endl;

	return 0;
}