Go: package main

import (
	"fmt"
	"sort"
)

type Edge struct {
	I int
	J int
	A int
}

func main() {
	var n int
	fmt.Scan(&n)

	g := make([][]int, n)
	edges := make([]Edge, 0, n*(n-1)/2)
	parents := make([]int, n)
	for i := 0; i < n; i++ {
		g[i] = make([]int, n)
		for j := 0; j < n; j++ {
			fmt.Scan(&g[i][j])
			if g[i][j] >= 0 {
				edges = append(edges, Edge{i, j, g[i][j]})
			}
		}
		parents[i] = i
	}
	sort.SliceStable(edges, func(i, j int) bool { return edges[i].A >= edges[j].A })

	sum := 0
	num := 0
	for len(edges) > 0 && num < n-1 {
		edge := edges[len(edges)-1]
		edges = edges[:len(edges)-1]

		if same(edge.I, edge.J, &parents) {
			continue
		}
		union(edge.I, edge.J, &parents)
		sum += edge.A
		num += 1
	}
	fmt.Println(sum)
}



func root(id int, parents *[]int) int {
	if id == (*parents)[id] {
		return id
	}
	return root((*parents)[id], parents)
}

func union(i, j int, parents *[]int) {
	(*parents)[root(j, parents)] = (*parents)[root(i, parents)]
}

func same(i, j int, parents *[]int) bool {
	return root(i, parents) == root(j, parents)
}

C++: #define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstdlib>
#include <string>
#include <iostream>
#include <climits>
#include <list>
#include <queue>

using namespace std;

static const int INFTY = 2001;

int main() {
	int Dist[101];
	int AdjacenceyList[100][100];
	int AdjacenceyWeightList[100][100];
	int Degree[100];
	int i, j;
	int N;
	int W;
	int Deg;
	int MinTotalWeight = 0;
	int u, v;
	int PrevSecondSmallestVertex;
	int SecondSmallestVertex;
	int MinVertex;
	bool inT[100];

	cin >> N;

	for (i = 0; i < N; i++) {
		inT[i] = false;
		Dist[i] = INFTY;
		Deg = -1;
		for (j = 0; j < N; j++) {
			cin >> W;
			if(W != -1){
				AdjacenceyList[i][++Deg] = j;
				AdjacenceyWeightList[i][Deg] = W;
			}
		}
		Degree[i] = Deg + 1;
	}
	Dist[100] = INFTY;

	u = 0;
	inT[u] = true;
	Dist[u] = 0;
	PrevSecondSmallestVertex = 100;
	for (i = 1; i <= N - 1; i++) {
		MinVertex = 100;
		for (j = 0; j < Degree[u]; j++) {
			v = AdjacenceyList[u][j];
			if (inT[v] == false) {
				W = AdjacenceyWeightList[u][j];
				if (W < Dist[v]) {
					Dist[v] = W;
				}
				if (Dist[v] < Dist[MinVertex]) {
					SecondSmallestVertex = MinVertex;
					MinVertex = v;
				}
				else if (Dist[v] < Dist[SecondSmallestVertex]) {
					SecondSmallestVertex = v;
				}
			}
		}

		////DEBUG
		//cout << "MinVerTex = " << MinVertex << " SecondSmallestVertex = " << SecondSmallestVertex << endl;

		if (Dist[PrevSecondSmallestVertex] < Dist[MinVertex]) {
			SecondSmallestVertex = MinVertex;
			MinVertex = PrevSecondSmallestVertex;
			PrevSecondSmallestVertex = SecondSmallestVertex;
		}
		else if (Dist[SecondSmallestVertex] < Dist[PrevSecondSmallestVertex]) {
			PrevSecondSmallestVertex = SecondSmallestVertex;
		}
		inT[MinVertex] = true;
		u = MinVertex;
		MinTotalWeight += Dist[MinVertex];

		////DEBUG
		//cout << "MinVertex = " << MinVertex << " PrevSecondSmallestVertex = " << PrevSecondSmallestVertex << endl;
		//cout << "inT: ";
		//for (int k = 0; k < N; k++) {
		//	cout << inT[k] << " ";
		//}
		//cout << endl;
		//printf("MinTotalWeight = %d\n", MinTotalWeight);
	}
	printf("%d\n", MinTotalWeight);

	return 0;
}

C++: #include<bits/stdc++.h>
#define ll long long
#define rep(i, n) for(int i=0; i<n; i++)
#define REP(i, n) for(int i=0; i<=n; i++)
#define repr(i, n) for(int i=n; i>0; i--)
#define REPR(i, n) for(int i=n; i>=0; i--)
const ll INF = 1LL<<60;
const int INT_INF = 1e9;
const ll MOD = 1e9+7;
template<class T> void puts(T x) { std::cout << x << std::endl; }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
using namespace std;

struct UnionFind {
    vector<int> parent;

    // Constructor
    UnionFind(int n) {
        parent.resize(n);
        rep(i, n) parent[i] = i;
    }

    // データxが属する木の代表元を返す
    int root(int x) {
        if (parent[x] == x) {
            return x;
        } else {
            parent[x] = root(parent[x]);
            return parent[x];
        }
    }

    // データxとyを同じ木にくっつける
    void connect(int x, int y) {
        int rx = root(x);
        int ry = root(y);

        if (rx == ry) return;
        parent[rx] = ry;
    }

    // データxとyが同じ木に属するか判定する
    bool check(int x, int y) {
        int rx = root(x);
        int ry = root(y);
        return rx == ry;
    }
};

struct Edge {
    int u;
    int v;
    int weight;

    Edge(int _u, int _v, int w) {
        u = _u;
        v = _v;
        weight = w;
    }

    bool operator >(const Edge other) const {
        return weight > other.weight;
    }

    bool operator ==(const Edge other) const {
        return weight == other.weight;
    }

    bool operator <(const Edge other) const {
        return weight < other.weight;
    }
};

vector<Edge> adj;

int main() {
    int n; cin >> n;
    for (int u = 0; u < n; u++) {
        for (int v = 0; v < n; v++) {
            int w; cin >> w;
            if (v > u && w != -1) adj.emplace_back(Edge(u, v, w));
        }
    }
    sort(adj.begin(), adj.end());

    // for (auto &edge: adj) {
    //     printf("(%d, %d, %d)\n", edge.u, edge.v, edge.weight);
    // }
    // cout << "-----" << endl;

    UnionFind tree(n);
    vector<Edge> s;
    for (auto &edge: adj) {
        // printf("check (u, v, w) = (%d, %d, %d)->", edge.u, edge.v, edge.weight);
        if (!tree.check(edge.u, edge.v)) {
            // printf("connect\n");
            s.emplace_back(edge);
            tree.connect(edge.u, edge.v);
        } else {
            // printf("don't connect\n");
        }
    }

    int ans = 0;
    for (auto &edge: s) {
        // printf("(%d, %d, %d)\n", edge.u, edge.v, edge.weight);
        ans += edge.weight;
    }
    cout << ans << endl;
}

C++: #include <iostream>
using namespace std;
static const int MAX = 100;
static const int INFTY = (1<<21);

int main()
{
  int n;
  int M[MAX][MAX];

  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) ? INFTY : e;
    }
  }

  int d[MAX], p[MAX];
  bool visited[MAX];
  for (int i = 0; i < n; ++i)
  {
    d[i] = INFTY;
    p[i] = -1;
    visited[i] = false;
  }
  d[0] = 0;

  while (true)
  {
    int minv = INFTY;
    int u = -1;
    for (int v = 0; v < n; ++v)
    {
      if (!visited[v] && minv > d[v])
      {
        minv = d[v];
        u = v;
      }
    }
    if (u == -1) break;

    visited[u] = true;
    for (int v = 0; v < n; ++v)
    {
      if (!visited[v] && M[u][v] != INFTY)
      {
        if (d[v] > M[u][v])
        {
          d[v] = M[u][v];
          p[v] = u;
        }
      }
    }
  }

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

  cout << sum << endl;

  return 0;
}