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>
using namespace std;
#define MAX 100
static const int WHITE=0;
static const int GRAY=1;
static const int BLACK=2;

int n,d[MAX+10],p[MAX+10],color[MAX+10];
int W[MAX+10][MAX+10];

int prim()
{
  int v,k,mini,flag,u=0;
  for(int i=0;i<n;i++)
  {
      d[i]=INT_MAX;
      p[i]=-1;
  }
  d[0]=0;
  while(1)
  {
      mini=INT_MAX;
      flag=1;
      for(int i=0;i<n;i++)
      {
          if(d[i]<mini&&color[i]!=BLACK)
          {
              u=i;
              mini=d[i];
              flag=0;
          }
      }
      if(flag) break;
      color[u]=BLACK;
      for(v=0;v<n;v++)
      {
          if(W[u][v]!=INT_MAX&&color[v]!=BLACK)
          {
            if(d[v]>W[u][v])
            {
              d[v]=W[u][v];//更新当前点到最小生成树的距离
              p[v]=u;//每一轮都需要跑更新前驱结点
            }
          }
      }
  }
  int sum=0;
  for(int i=0;i<n;i++)
  {
      if(p[i]!=-1) sum+=W[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;
         W[i][j]=(e==-1)?INT_MAX:e;
        }
        color[i]=WHITE;
    }
    cout<<prim()<<endl;
}

C++: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using vi = vector<int>;    using vvi = vector<vi>;
using vb = vector<bool>;   using vvb = vector<vb>;
using vl = vector<ll>;     using vvl = vector<vl>;
using vd = vector<double>; using vvd = vector<vd>;

#define REP(i,n) for(auto i = 0 * n; i < (n); ++i)
#define ALL(c) (c).begin(), (c).end()
#define FOR(i,s,e) for (ll i = s; i < (ll)e; i++)
#define TEN(x) ((ll)1e##x)

class UnionFind {
	typedef size_t U;
	vector<int32_t> v;
public:
	UnionFind(U n) : v(n, -1) {}
	U find(U x) { return v[x] < 0 ? x : (v[x] = find((U)v[x])); }
	bool same(U x, U y) { return find(x) == find(y); }
	U size(U x) { return (U)-v[find(x)]; }
	void unite(U x, U y) {
		x = find(x); y = find(y);
		if (x != y) {
			if (-v[x] < -v[y]) swap(x, y);
			v[x] += v[y];
			v[y] = x;
		}
	}
};

struct Edge{ uint32_t to, id; };
typedef vector<vector<Edge>> Graph;

template<class T> struct Kruskal{
	typedef uint32_t U;
	template<class V> Kruskal(U n, const V & u, const V & v, const vector<T> & w) : g(n) {
		vector<U> es(w.size());
		iota(es.begin(), es.end(), 0);
		sort(es.begin(), es.end(), [&](U i, U j) { return w[i] < w[j]; });
		UnionFind uf(n);
		for (U i : es) {
			if (!uf.same(u[i], v[i])) {
				uf.unite(u[i], v[i]); cost += w[i];
				g[u[i]].push_back(Edge{ v[i], i }); g[v[i]].push_back(Edge{ u[i], i });
			}
		}
	}
	Graph g; T cost = 0;
};

int main() {
	cin.tie(0);
	ios_base::sync_with_stdio(false);
	cout << fixed << setprecision(50);

	ll n; cin >> n;
	vl u, v, w;
	REP(i, n) REP(j, n) {
		ll x; cin >> x;
		if (x != -1) {
			u.push_back(i);
			v.push_back(j);
			w.push_back(x);
		}
	}
	Kruskal<ll> mst(n, u, v, w);
	cout << mst.cost << endl;
}

C++: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;

#define rep(i, n) REP(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define MSG(a) cout << #a << " " << a << endl;
#define REP(i, x, n) for (int i = x; i < n; i++)
#define OP(m) cout << m << endl
typedef long long ll;
typedef unsigned long long ull;

int main()
{
    int n, sum = 0;
    cin >> n;
    int m[n][n];
    rep(i, n) rep(j, n) cin >> m[i][j];

    rep(i, n) rep(j, n) if (m[i][j] == -1) m[i][j] = 1e7;

    int d[n];
    rep(i, n) d[i] = 1e7;
    bool used[n] = {};
    d[0] = 0;
    while (1)
    {

        int minv = 1e7;
        int u = -1;
        rep(i, n)
        {
            if (!used[i] && d[i] < minv)
            {
                minv = d[i];
                u = i;
            }
        }
        if (u == -1)
            break;

        sum += minv;
        used[u] = true;

        rep(i, n)
        {

            if (!used[i] && m[u][i] != 1e7 && d[i] > m[u][i])
                d[i] = m[u][i];
        }
    }

    OP(sum);

    return 0;
}