Go: package main

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

// Define disjoint-set forests

type vertexNo int

type vertex struct {
	number vertexNo
	rank int
	parent *vertex
}

func makeSet(number vertexNo) vertex {
	return vertex {
		number: number,
		rank: 0,
		parent: nil,
	}
}

func union(x, y *vertex) *vertex {
	return link(findSet(x), findSet(y))
}

func link(x, y *vertex) *vertex {
	if x.rank > y.rank {
		y.parent = x
		return x
	} else {
		x.parent = y
		if x.rank == y.rank {
			y.rank += 1
		}
		return y
	}
}

func findSet(v *vertex) *vertex {
	if v.parent == nil {
		return v
	}
	v.parent = findSet(v.parent)
	return v.parent
}

// Function to calculate minimum spanning tree

type matrix [][]int

type edge struct {
	one vertexNo
	two vertexNo
	weight int
}

const(
	MAX_VERTICES = 100
)

func newEdgesFromMatrix(matrix matrix) []edge {
	edges := make([]edge, 0, MAX_VERTICES * MAX_VERTICES)

	for i := 0; i < len(matrix); i++ {
		row := matrix[i]
		for j := i; j < len(row); j++ {
			if row[j] >= 0 {
				edge := edge{one: vertexNo(i+1), two: vertexNo(j+1), weight: row[j]}
				edges = append(edges, edge)
			}
		}
	}

	return edges
}

func solve(matrix matrix) int {
	nVertices := len(matrix)

	// initialize vertices
	vertices := make([]vertex, nVertices)
	for i := 0; i < nVertices; i++ {
		vertices[i] = makeSet(vertexNo(i+1))
	}

	// prepare edges sorted in the ascending order of weight
	edges := newEdgesFromMatrix(matrix)
	sort.Slice(edges, func(i, j int) bool {
		return edges[i].weight < edges[j].weight
	})

	unionCount := 0
	weightSum := 0
	for unionCount < nVertices-1 {
		for i := 0; i < len(edges); i++ {
			edge := edges[i]
			v1 := &vertices[edge.one-1]
			v2 := &vertices[edge.two-1]
			rep1 := findSet(v1)
			rep2 := findSet(v2)
			if rep1.number == rep2.number {
				continue
			}
			union(rep1, rep2)
			edges = append(edges[0:i], edges[i+1:]...)
			weightSum += edge.weight
			unionCount++
			break
		}
	}

	return weightSum
}

// main

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

	n, err := nextInt(sc)
	if err != nil {
		panic(err)
	}

	matrix := parseMatrix(n, sc)

	edges := newEdgesFromMatrix(matrix)
	sort.Slice(edges, func(i, j int) bool {
		return edges[i].weight < edges[j].weight
	})

	fmt.Println(solve(matrix))
}

func parseMatrix(n int, sc *bufio.Scanner) [][]int {
	matrix := make([][]int, n)
	for i := 0; i < n; i++ {
		matrix[i] = make([]int, n)
		for j := 0; j < n; j++ {
			x, err := nextInt(sc)
			if err != nil {
				panic(err)
			}
			matrix[i][j] = x
		}
	}
	return matrix
}

func nextText(sc *bufio.Scanner) string {
	sc.Scan()
	return sc.Text()
}

func nextInt(sc *bufio.Scanner) (int, error) {
	return strconv.Atoi(nextText(sc))
}

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

int x[10000][10000];
int MIN[10000];
int MINX = 0;
int MINZ = 10000000;

int main() {
	memset(MIN, 127, sizeof(MIN));
	int n, a;
	cin >> n;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> a;
			x[i][j] = a;
		}
	}
	for(int i=0;i<n;i++){
	    for(int j=0;j<n;j++){
	        if(x[i][j]!=-1){
	            MIN[i]=min(x[i][j],MIN[i]);
	        }
	    }
	}
	for(int i=0;i<n;i++){
	    MINX=0;
	    for(int j=0;j<n;j++){
	        MINX += min[j];
	    }
	    MINZ=min(MINZ,MINX);
	}
	cout<<MINZ<<endl;
	return 0;
}

C++: #include<stdio.h>

static const int MAX = 500;
static const int INFTY = (1<<21);

main(){
  int n, i, j, e, sum,M[MAX][MAX]={0};
  int u,minV,INT_MAX,A[MAX]={INFTY},key[MAX]={INFTY};
  /*

    your code


   */

  scanf("%d", &n);
  
  for ( i = 0; i< n; i++ ){
    for ( j = 0; j < n; j++ ){
      scanf("%d", &e);
      M[i][j] = (e==-1)?INFTY:e;
    }
  }
  
  
  while(1){
    minV = 
      for(i=1;i<=n;i++){
        if((i < minV) && 

  






















  sum = 0;

  for ( i = 0; i < n; i++ ){
    if ( p[i] != -1 ) sum += M[i][p[i]];
  }

  printf("%d\n", sum);

  retur
}

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

static const int MAX = 100;
static const int INFTY = 3000;
static const int WHITE = 0, GRAY = 1, BLACK = 2;

int n;
int A[MAX][MAX];

int prim() {
	int i1, j1, min;
	int p[MAX], color[MAX], d[MAX];

	for (int i = 0; i < n; i++)	{
		p[i] = -1; //MST??????????????????i??????
		color[i] = WHITE; 
		d[i] = INFTY; //MST??¨????????\????????????????°??????¢
	}
	d[0] = 0;

	while (1) {
		min = INFTY;
		i1 = -1;
		for (int i = 0; i < n; i++)	{
			if (d[i] < min && color[i] != BLACK) {
				i1 = i;
				min = d[i];
			}
		}
		if (i1 == -1) break;

		color[i1] = BLACK;
		for (int j = 0; j < n; j++)	{
			if (A[i1][j] != INFTY && color[j] != BLACK) {
				if (d[j] > A[i1][j]) {
					d[j] = A[i1][j];
					p[j] = i1;
					color[j] = GRAY;
				}
			}
		}
	}
	int sum = 0;
	for (int i = 0; i < n; i++)	{
		if (p[i] != -1) sum += A[i][p[i]];
	}
	return sum;
}

int main() {
	int i1,j1;
	cin >> n;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			int t;
			cin >> t;
			A[i][j] = (t == -1) ? INFTY : t;
		}
	}

	cout << prim() << endl;

	return 0;
}

C++: #include<iostream>

using namespace std;

static const int N = 100;
static const int I=(1<<21);
static const int W= 0;
static const int G =1;
static const int B =2;

int n,M[N][N];

int prim(){
  int u,minv,d[N],p[N],color[N];
  for(int i=0;i<n;i++){
    d[i]=I;
    p[i]=-1;
    color[i]=W;
  }

  d[0]=0;

  while(1){
    minv=I;
    u=-1;
    for(int i=0;i<n;i++){
      if(minv>d[i]&&color[i]!=B){
        u=i;
        minv=d[i];
      }
    }
    if(u==-1)break;
    color[u]=B;
    for(int v=0;v<n;v++){
      if(color[v]!=B&&M[u][v]!=I){
        if(d[v]>M[u][v]){
          d[v]=M[u][v];
          p[v]=u;
          color[v]=G;  
            
            
        }}
    }
  }
  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) ? I : e;
    }
  }

  cout<<prim()<<endl;

  return 0;
}

C++: #include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

template <class T>
using gp_queue=priority_queue<T, deque<T>, less<T>>;

using Weight=int;
using DArray=vector<Weight>;
using DMatrix=vector<DArray>;

static const Weight INF=1<<29;

struct Edge {
    size_t src, dst;
    Weight weight;
    Edge() {}
    Edge(size_t src, size_t dst, Weight weight=1):
        src(src), dst(dst), weight(weight)
    {}
};

bool operator<(const Edge &e, const Edge &f) {
    if (e.weight != f.weight) {
        return e.weight > f.weight;
    } else {
        return e.src!=f.src? e.src<f.src : e.dst<f.dst;
    }
}

using Edges=vector<Edge>;
using Vertex=vector<Edge>;
using Graph=vector<Vertex>;

void join(Graph &g, size_t s, size_t d, Weight w=1) {
    // non-directed
    g[s].push_back(Edge(s, d, w));
    g[d].push_back(Edge(d, s, w));
}

void connect(Graph &g, size_t s, size_t d, Weight w=1) {
    // directed
    g[s].push_back(Edge(s, d, w));
}

pair<Weight, Edges> minimum_spanning_tree(const Graph &g, size_t s=0) {
    /* Prim */
    size_t V=g.size();
    Edges T;
    Weight total=0;

    vector<bool> visited(V);
    gp_queue<Edge> q; q.push(Edge(-1, s, 0));
    while (!q.empty()) {
        Edge e=q.top(); q.pop();
        if (visited[e.dst]) continue;

        T.push_back(e);
        total += e.weight;
        visited[e.dst] = true;
        for (const Edge &f: g[e.dst])
            if (!visited[f.dst])
                q.push(f);
    }

    return make_pair(total, T);
}

int main() {
    size_t n;
    scanf("%zu", &n);

    Graph g(n);
    for (size_t i=0; i<n; ++i)
        for (size_t j=0; j<n; ++j) {
            Weight a;
            scanf("%d", &a);

            if (a > -1)
                connect(g, i, j, a);
        }

    printf("%d\n", minimum_spanning_tree(g).first);
    return 0;
}