Go: package main

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

const BIG_COST = 3000

const (
	ST_NOT_YET = iota
	ST_JOINED
)

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)

	nNodes := scanInt(sc)
	costs := make([][]int, nNodes)

	for r := 0; r < nNodes; r++ {
		costs[r] = make([]int, nNodes)
		for c := 0; c < nNodes; c++ {
			costs[r][c] = scanInt(sc)
		}
	}

	states := make([]int, nNodes)
	minCosts := make([]int, nNodes)

	for i := 1; i < nNodes; i++ {
		minCosts[i] = BIG_COST
	}

	for {
		var u int
		minCost := BIG_COST

		for i := 0; i < nNodes; i++ {
			if states[i] != ST_JOINED && minCosts[i] < minCost {
				minCost = minCosts[i]
				u = i
			}
		}

		// 全てのノードが MST に JOIN できたので終了。
		if minCost == BIG_COST {
			break
		}

		states[u] = ST_JOINED

		for v := 0; v < nNodes; v++ {
			cost := costs[u][v]

			// MST内の u と MST外の v との辺の重みをそれぞれ minCosts[v] として
			// 保存しておく。このうち辺の重みが最小となる v が次のループで MST に JOIN する。
			if states[v] != ST_JOINED && cost != -1 && cost < minCosts[v] {
				minCosts[v] = cost
			}
		}
	}

	sum := 0
	for _, cost := range minCosts {
		sum += cost
	}
	fmt.Println(sum)
}

func scanInt(sc *bufio.Scanner) int {
	sc.Scan()
	v, _ := strconv.Atoi(sc.Text())
	return v
}

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;
}

C++: //最小生成树Prim算法
#include <iostream>

using namespace std;

const int N = 100;
const int INFTY = 1 << 14; //赋值无穷大

int n; //图的规模

short  Graph[N][N];

int *p; //p[i]记录着它们之间最小权值那个路径上，i的父节点
int *d;//d[i]标记着从i的父节点到i所需的最小权值
char *color; //标记节点是否访问状态


void prim() { //普莱姆算法
    for (int i=0;i<n;i++) {
    	d[i] = INFTY;
    	color[i] = 'W';
	}
	//普莱姆算法选取任意点作为开始点，这里我们选取第一个点 
	p[0] = INFTY;
	d[0] = 0;
	
	while (1) {
		
		//每次从剩余点中选取权值最小的点 
		int mincost = INFTY;
		int u;
		for (int i=0;i<n;i++) {
			if (color[i] != 'B' && mincost > d[i]) {
				mincost = d[i];
				u = i;
			}
		}
		
		if (mincost == INFTY) { //说明所有节点已经访问完毕 
			break;
		}
		
		color[u] = 'B'; //标记节点已经访问结束 
		
		for (int v=0;v<n;v++) {
			if (color[v] != 'B' && Graph[u][v] != INFTY) {
				if (d[v] > Graph[u][v]) {
					d[v] = Graph[u][v];
					p[v] = u;
					color[v] = 'G';
				}
			}
		}
	}
	
}

int main() {
	cin >> n;
	p = new int[n];
	d = new int[n];
	color = new char[n];

	for (int i=0; i<n; i++) {
		for (int j = 0; j<n; j++) {
			cin >> Graph[i][j];
			if (Graph[i][j] == -1) {
				Graph[i][j] = INFTY;
			}
		}
	}
	
	prim();
	int sum = 0;
	for (int i=0; i<n; i++) {
		if (p[i] != INFTY) {
			sum += Graph[i][p[i]];
		}
	}
	cout << sum << endl;
	delete[] p;
	delete[] d;
	delete[] color;
	return 0;
}