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 <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <utility>

using namespace std;

#define REP(var, count) for(int var=0; var<count; var++)

struct unionf {
	
	vector<int> data;
	
	unionf(int n) {
		REP(i, n+1) { data.push_back(i); }
	}
	
	int root(int a) {
		if(data[a] == a) { return a; }
		return (data[a] = root(data[a]));
	}
	
	bool issame(int a, int b) {
		return root(a) == root(b);
	}
	
	void unite(int a, int b) {
		data[root(a)] = root(b);
	}

};

int main(void) {
	int N;
	cin >> N;
	
	vector<pair<int, pair<int, int> > > edge;
	
	REP(x, N) {
		REP(y, N) {
			int c;
			cin >> c;
			if ( x <= y ) { continue; }
			if ( c == -1 ) { continue; }
			edge.push_back( make_pair(c, make_pair(x,y)) );
		}
	}
	
	sort(edge.begin(), edge.end());
	
	unionf uf(N);
	
	int cnt = 0;
	int ret = 0;
	
	REP(i, edge.size() ) {
		
		pair<int, int> sd = edge[i].second;
		if ( ! uf.issame( sd.first, sd.second ) ) {
			cnt ++;
			ret += edge[i].first;
			uf.unite(sd.first, sd.second);
			//cout << "joint " << sd.first << " " << sd.second << " -> " << edge[i].first << endl;
		}
		
		if ( cnt == N-1 ) { break; }
	}
	
	cout << ret << endl;
}

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

// =======================
// ------ graph ------ //
using Weight = int;
using Flow = int;
struct Edge {
    int src, dst;
    Weight weight;
    Flow cap;
    Edge() : src(0), dst(0), weight(0) { }
    Edge(int s, int d, Weight w) : src(s), dst(d), weight(w) { }
};
bool operator < (const Edge &e, const Edge &f) {
    return e.weight != f.weight ? e.weight < f.weight :
        e.src != f.src ? e.src < f.src : e.dst < f.dst;
}
using Edges = vector<Edge>;
using Graph = vector<Edges>;

void add_edge1(Graph &g, int a, int b, Weight w = 1) {
    g[a].emplace_back(a, b, w);
}

// ------ disjoint set ------ //
struct UnionFind {
    vector<int> data;
    int __size;
    UnionFind(int size) : data(size, -1), __size(size) { }
    bool unionSet(int x, int y) {
        if ((x = root(x)) != (y = root(y))) {
            if (data[y] < data[x]) swap(x, y);  // par -> child とは限らない
            data[x] += data[y]; data[y] = x; __size--;
        }
        return x != y;
    }
    bool findSet(int x, int y) { return root(x) == root(y); }
    int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
    int size(int x) { return -data[root(x)]; }
    int size() { return __size; }
    vector<int> subset_roots() {
        vector<int> roots;
        for (int i = 0; i < data.size(); i++) if (data[i] < 0) roots.push_back(i);
        return roots;
    }
};

// ------ kruskal ------ //
pair<Weight, Edges> kruskal(const Graph &g) {
    UnionFind uf(g.size());
    Edges es;
    for (auto &adj : g) for (auto &e : adj) es.emplace_back(e);
    sort(es.begin(), es.end());
    Weight total = 0;
    Edges T;
    for (auto &e : es) if (uf.unionSet(e.src, e.dst)) {
        T.push_back(e);
        total += e.weight;
    }
    return make_pair(total, T);
}
// =======================

int main() {
    int n; cin >> n;
    Graph G(n);
    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {
        int w; cin >> w;
        if (w >= 0) add_edge1(G, i, j, w);
    }
    pair<Weight, Edges> res = kruskal(G);
    cout << res.first << endl;
    return 0;
}

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

const int MAX = 100;

int count(bool check[MAX], int graph[MAX][MAX], int n,int i) {
	check[i] = true;
	int sum = 0;
	for (int j = 0; j < n; j++) {
		if (graph[i][j] != -1 && check[j] == false) {
			sum += count(check,graph, n, j);
			sum += graph[i][j];
		}
	}
	return sum;
}

int main() {
	int n;
	int g;
	int graph[MAX][MAX];

	cin >> n;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> graph[i][j];
		}
	}

	//?????±???
	for (int m = 0; m < n; m++) {
		//?§????
		for (int b = 0; b < n; b++) {
			if (graph[b][m] == -1)continue;
			//??????
			for (int e = 0; e < n; e++) {
				if (graph[m][e] == -1 || graph[b][e] == -1)continue;
				if (graph[b][e] >= graph[b][m] + graph[m][e]) {
					graph[b][e] = -1;
				}
			}
		}
	}

	bool check[MAX] = { false };
	cout << count(check, graph, n, 0) << endl;
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;

void solve(){
  int n; cin >> n;
  vector<vector<int> > v(n, vector<int>(n));
  for(int i = 0; i < n; i++){
    for(int j = 0; j < n; j++){
      cin >> v[i][j];
    }
  }
  vector<int> t, c(n);
  t.push_back(0);
  c[0] = 1;
  int ans = 0;
  while(t.size() != n){
    int mini, minj, mint = 100000;
    for(int i = 0; i < t.size(); i++){
      for(int j = 0; j < n; j++){
        if(v[t[i]][j] >= 0 && c[j] == 0){
          if(v[t[i]][j] < mint){
            mini = i;
            minj = j;
            mint = v[t[i]][j];
          }
        }
      }
    }
    ans += mint;
    t.push_back(minj);
    c[minj] = 1;
  }
  cout << ans << endl;
  return;
}

int main(){
  solve();
  return 0;
}