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

int n,m[MAX][MAX];

int prim(){
  int u,minv;
  int d[MAX],p[MAX],color[MAX];

  for(int i=0;i<n;i++){
    d[i]=INFTY;
    p[i]=-1;
    color[i]=WHITE;
  }

  d[0]=0;

  while(1){
    minv=INFTY;
    u=-1;
    for(int i=0;i<n;i++){
      if(minv>d[i]&&color[i]!=BLACK){
	u=i;
	minv=d[i];
      }
    }
    if(u==-1) break;
    color[u]=BLACK;
    for(int v=0;v<n;v++){
      if(color[v]!=BLACK&&m[u][v]!=INFTY){
	if(d[v]>m[u][v]){
	  d[v]=m[u][v];
	  p[v]=u;
	  color[v]=GRAY;
	}
      }
    }
  }
  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)?INFTY:e;
    }
  }
  cout<<prim()<<endl;

  return 0;
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <utility>
#include <numeric>
#include <array>
#include <cmath>
#include <memory>
using namespace std;
//変数デバッグ
#define DEB(variable) cout << #variable << '=' << variable << endl

//for簡易表記(引数ミス防止)
#define FOR(LoopVariable,numberOFbegin,numberOFend) for (int LoopVariable = (numberOFbegin); (LoopVariable) < (numberOFend); (LoopVariable)++)
#define DEFOR(LoopVariable,numberOFbegin,numberOFend) for (int LoopVariable = (numberOFbegin)-1; (LoopVariable) >= (numberOFend); (LoopVariable)--)
#define REP(LoopVariable,numberOFend) for(int LoopVariable = 0;(LoopVariable)<(numberOFend);LoopVariable++)

constexpr long long int linf = numeric_limits<long long int>::max()-5;
constexpr int inf= numeric_limits<int>::max()-5;
constexpr long long int mod = 1000000007;



template<typename T>
class Wgraph{
public:
    //隣接行列の入力を受ける
    Wgraph(int _n){
        n = _n;
        mat.resize(n, vector<int>(n));
        colors.resize(n);
        min_weis.resize(n);
        parents.resize(n);
        REP(i,n){
            REP(j,n){
                scanf("%d", &mat[i][j]);
                if(mat[i][j]==-1){
                    mat[i][j] = inf;
                }
            }
        }

    }

    long long int prim(){
        REP(i,n){
            colors[i] = 0;
            parents[i] = -1;
            min_weis[i] = inf;
        }
        int u,mincost;
        min_weis[0] = 0;
    

        while(1){
            mincost = inf;
            u = -1;
            REP(i,n){
                if(colors[i]!=2&&min_weis[i]<mincost){
                    mincost = min_weis[i];
                    u = i;
                }
            }

            if(u==-1){
                break;
            }

            colors[u] = 2;
            REP(i,n){
                if(colors[i]!=2){
                    if(mat[u][i]<min_weis[i]){
                        min_weis[i] = mat[u][i];
                        parents[i] = u;
                        colors[i] = 1;
                    }
                }
            }
        }
        int sum = 0;
        REP(i,n){
            if(parents[i]!=-1){
                sum += mat[i][parents[i]];
            }
        }
        return sum;
    }

private:
    vector<vector<int>> mat;
    int n;

    vector<int> colors,min_weis, parents;
};


int main(){

    int n;
    cin>>n;
    unique_ptr<Wgraph<int>> wg(new Wgraph<int>(n));

    cout << wg->prim() << endl;
    return 0;
}

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

constexpr int MAX = 110;
constexpr int INF = 1e9;

int N;
int G[MAX][MAX];
bool seen[MAX];
int par[MAX];
int d[MAX];

int main(){
  cin >> N;
  for( int i = 0; i < N; i++ ){
    for( int j = 0; j < N; j++ ){
      cin >> G[i][j];
      if( G[i][j] == -1 ) G[i][j] = INF;
    }
  }

  for( int i = 0; i < MAX; i++ ){
    par[i] = -1;
    d[i] = INF;
  }
  d[0] = 0;

  while( 1 ){
    int mincost = INF;
    int u;
    for( int i = 0; i < N; i++ ){
      if( d[i] < mincost && !seen[i] ){
	mincost = d[i];
	u = i;
      }
    }

    if( mincost == INF ) break;
    seen[u] = true;
    
    for( int i = 0; i < N; i++ ){
      if( G[u][i] != INF && !seen[i] ){
	if( G[u][i] < d[i] ){
	  d[i] = G[u][i];
	  par[i] = u;
	}
      }
    }
  }

  int ans = 0;
  for( int i = 1; i < N; i++ ){
    ans += G[par[i]][i];
  }

  cout << ans << endl;
}

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

struct edge{ int a,b,cost; };

int parent[100],height[100];

bool comp(const edge& e1,const edge& e2){
	return e1.cost < e2.cost;
}

int find(int x){
	if(parent[x] == x) return x;
	else return parent[x] = find(parent[x]);
}

void unite(int x,int y){
	x = find(x);
	y = find(y);
	if(x == y) return;
	if(height[x] < height[y]){
		parent[x] = y;
	}else {
		parent[y] = x;
		if(height[x] == height[y]) height[x]++;
	}
}

bool same(int x,int y){
	return find(x) == find(y);
}

int main(){
	int n,res = 0;
	cin >> n;
	vector<edge> es;
	for(int i = 0;i < n;i++) parent[i] = i;
	for(int i = 0;i < n;i++){
		for(int j = 0;j < n;j++){
			int t;
			cin >> t;
			if(t != -1) es.push_back({i,j,t});
		}
	}
	sort(es.begin(),es.end(),comp);
	for(int i = 0;i < es.size();i++){
		edge e = es[i];
		if(!same(e.a,e.b)){
			unite(e.a,e.b);
			res += e.cost;
		}
	}
	cout << res << endl;
	return 0;
}