Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

func nextString() string {
	scanner.Scan()
	return scanner.Text()
}

func nextInt() int {
	n, err := strconv.Atoi(nextString())
	if err != nil {
		fmt.Printf("strconv.Atoi failed: %v\n", err)
	}
	return n
}

type ElementKey int
type Node struct {
	key    ElementKey
	parent *Node
	rank   int
}

func newNode(key ElementKey) *Node {
	node := Node{}
	node.key = key
	node.parent = &node
	node.rank = 0

	return &node
}

func union(x, y *Node) {
	xSet := findSet(x)
	ySet := findSet(y)
	link(xSet, ySet)
}

func link(x, y *Node) {
	if x.rank > y.rank {
		y.parent = x
	} else {
		x.parent = y

		if x.rank == y.rank {
			y.rank++
		}
	}
}

func findSet(x *Node) *Node {
	if x != x.parent {
		x.parent = findSet(x.parent)
	}
	return x.parent
}

func newDisjointSets(nSets int) *DisjointSets {
	sets := DisjointSets{}
	sets.keyToNode = map[ElementKey]*Node{}
	for i := 0; i < nSets; i++ {
		key := ElementKey(i)
		sets.keyToNode[key] = newNode(key)
	}
	return &sets
}

type DisjointSets struct {
	keyToNode map[ElementKey]*Node
}

func (sets *DisjointSets) union(x, y ElementKey) {
	xNode := sets.keyToNode[x]
	yNode := sets.keyToNode[y]
	union(xNode, yNode)
}

func (sets DisjointSets) findSet(x ElementKey) *Node {
	xNode := sets.keyToNode[x]
	return findSet(xNode)
}

type Edge struct {
	i, j   int
	weight int
}

func main() {
	scanner.Split(bufio.ScanWords)

	n := nextInt()
	sets := newDisjointSets(n)
	edges := []Edge{}
	a := make([][]int, n)
	for i := 0; i < n; i++ {
		a[i] = make([]int, n)
		for j := 0; j < n; j++ {
			a[i][j] = nextInt()
			if a[i][j] >= 0 {
				e := Edge{
					i:      i,
					j:      j,
					weight: a[i][j],
				}
				edges = append(edges, e)
			}
		}
	}
	sort.Slice(edges, func(i, j int) bool { return edges[i].weight < edges[j].weight })
	totalWeight := 0
	for _, edge := range edges {
		i := ElementKey(edge.i)
		j := ElementKey(edge.j)
		if sets.findSet(i) != sets.findSet(j) {
			totalWeight += edge.weight
			sets.union(i, j)
		}
	}
	fmt.Println(totalWeight)
}

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

const int M = 1000000007;

vector<vector<int>> adj;


struct Point {
    int id;
    // double x, y;
    Point() {}
    Point(int id) : id(id) {}
    // Point(double x, double y): x(x), y(y) {}
    int distance(const Point &p) const {
        return adj[id][p.id] == -1 ? M : adj[id][p.id];
    }
};

int calc_mst(const vector<Point>& points) {
    int n = points.size();
    vector<int> dist(n, M);
    vector<bool> visited(n);
    int p = 0;
    int res = 0;
    while (true) {
        visited[p] = true;
        int mind = M, minj = -1;
        for (int j = 0; j < n; ++j) {
            if (visited[j]) continue;
            dist[j] = min(dist[j], points[p].distance(points[j]));
            if (mind > dist[j]) {
                mind = dist[j];
                minj = j;
            }
        }
        if (minj == -1) break;
        p = minj;
        res += mind;
    }
    return res;
}

int main(int argc, char **argv) {
    int n;
    cin >> n;
    adj = vector<vector<int>>(n, vector<int>(n));
    vector<Point> p(n);
    for (int i = 0; i < n; ++i) {
        p[i] = Point(i);
        for (int j = 0; j < n; ++j) {
            cin >> adj[i][j];
        }
    }
    cout << calc_mst(p) << '\n';
    return 0;
}

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

int P[10010];
void init(int N){
  for (int i=0; i<N; i++) P[i] = i;
}
int root (int a){
  if (P[a] == a) return a;
  else {
    P[a] = root(P[a]);
    return P[a];
  }
}
bool is_same_set(int a, int b){
  return root(a) == root(b);
}
void unite(int a, int b){
  P[root(a)] = root(b);
}

int main(){
  int N;
  cin >> N;
  pair <int, int> edge[10010];
  for (int i=0; i<N; i++){
    for (int j=0; j<N; j++){
      cin >> edge[i*N+j].first;
      edge[i*N+j].second = i*N+j;
    }
  }
  sort(edge, edge+N*N);
  init(N);
  int ans = 0;
  int b = 0;
  for (int k=0; k<N*N; k++){
    while(edge[k].first < 0) k++;
    int i = edge[k].second / N;
    int j = edge[k].second % N;
    if (b == 0){ //グラフは非連結かもしれない?
      b = i;
      unite(i,j);
      ans += edge[k].first;
    }
    if (is_same_set(b,i) && is_same_set(b,j)){}
    else{
      unite(b,i);
      unite(b,j);
      ans += edge[k].first;
    }
  }
  cout << ans << endl;
}

C++: #include <iostream>
#include <iomanip>
#include <string>
#include <stack>
#include <vector>
#include <math.h>
#include <stdio.h>
#include <algorithm>
#include <utility>
#include <functional>
#include <map>
#include <set>
#include <queue>
#include <list>
using namespace std;
using pii  = pair<int,int>;
using ll=long long;
using ld=long double;
#define pb push_back
#define mp make_pair
#define rep(i,n) for(int i=0;i<(n);++i)
#define REP(i,a,b) for(int i=(a);i<(b);++i)
#define crep(i) for(char i='a';i<='z';++i)
#define psortsecond(A,N) sort(A,A+N,[](const pii &a, const pii &b){return a.second<b.second;});
#define ALL(x) (x).begin(),(x).end()
#define endl '\n'
int ctoi(const char c){
  if('0' <= c && c <= '9') return (c-'0');
  return -1;
}
long long gcd(long long a, long long b){return (b == 0 ? a : gcd(b, a%b));}
long long lcm(long long a, long long b){return a*b/gcd(a,b);}
constexpr ll MOD=1000000007;
constexpr ld EPS=10e-8;
template<typename T> istream& operator>>(istream& is,vector<T>& v){for(auto&& x:v)is >> x;return is;}
template<typename T,typename U> istream& operator>>(istream& is, pair<T,U>& p){ is >> p.first; is >> p.second; return is;}
template<typename T,typename U> ostream& operator>>(ostream& os, const pair<T,U>& p){ os << p.first << ' ' << p.second; return os;}
template<class T> ostream& operator<<(ostream& os, vector<T>& v){
    for(auto i=begin(v); i != end(v); ++i){
        if(i !=begin(v)) os << ' ';
        os << *i;
    }
    return os;
}

vector<pair<ll,pair<ll,ll>>> V;
ll length=0,N;
ll chek[107];
ll A[107][107];

void dfs(ll pt,ll c){
    chek[pt]=1;
    if(c==N){
        return;
    }
    rep(i,N){
        if(pt!=i){
            V.pb(mp(A[pt][i],mp(pt,i)));
        }
    }
    sort(ALL(V));
    rep(i,V.size()){
        if(chek[V[i].second.second]==0){
            length+=V[i].first;
            dfs(V[i].second.second,c+1);
            break;
        }
    }
}
 
int main(){
    cin>>N;
    rep(i,N){
        rep(j,N){
            cin >> A[i][j];
            if(A[i][j]==-1){
                A[i][j]=MOD;
            }
        }
    }
    rep(i,N){
        if(0!=i){
            V.pb(mp(A[0][i],mp(0,i)));
        }
    }
    dfs(0LL,0LL);
    cout  << length << endl;
}