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<bits/stdc++.h>

using namespace std;
#define rep(i,n) for(int i=0;i<(n);i++)

typedef long long ll;
typedef pair<int, int> P;

#define MAX 100005
#define INF INT_MAX

class Tree
{
    vector<int> rank, id; 
public:
    Tree(int n) : rank(n), id(n) {
        rep(i,n) id[i] = i;
    }
    int getId(int n) {
        if (n != id[n]) id[n] = getId(id[n]);
        return id[n];
    }
    void uniteTree(int u, int v) {
        u = getId(u);
        v = getId(v);
        if (rank[u] > rank[v]) swap(u,v);
        if (rank[u] == rank[v]) rank[v]++;
        id[u] = v;
    }

};

struct Edge
{
    int u, v;
    int cost;
    bool operator<(const Edge& e) const { return this->cost < e.cost; }
};

int main(int, char**)
{
    int n;
    cin >> n;

    vector<Edge> E;
    int tmp;
    rep(i,n) rep(j,n) {
        cin >> tmp;
        if (i >= j) continue;
        if (tmp == -1) continue;
        E.push_back({i,j,tmp});
    }

    sort(E.begin(), E.end());

    Tree tree(n);
    ll ans = 0;
    rep(i,E.size()) {
        int u = E[i].u;
        int v = E[i].v;
        if (tree.getId(u) != tree.getId(v)) {
            tree.uniteTree(u,v);
            ans += E[i].cost;
        }
    }

    cout << ans << endl;

    return 0;
}

C++: #include <iostream>
#include <queue>
#include <vector>

struct Edge {
  int dst;
  long long cost;
  Edge() {}
  Edge(int x, long long y) : dst(x), cost(y) {}
};

int prim(std::vector<std::vector<Edge>> &G) {
  const int V = (int)G.size();
  std::vector<bool> is_used(V, false);

  typedef std::pair<long long, int> PLI;
  std::priority_queue<PLI, std::vector<PLI>, std::greater<PLI>> que;
  que.push(std::make_pair(0LL, 0));

  int ret = 0;
  while (!que.empty()) {
    long long cost = que.top().first;
    int cur_v = que.top().second;
    que.pop();
    if (is_used[cur_v]) {
      continue;
    }
    is_used[cur_v] = true;
    ret += cost;
    for (int i = 0; i < (int)G[cur_v].size(); i++) {
      que.push(std::make_pair(G[cur_v][i].cost, G[cur_v][i].dst));
    }
  }
  return ret;
}

int main() {
  int n;
  std::cin >> n;

  std::vector<std::vector<Edge>> g(n);
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      int a;
      std::cin >> a;
      if (a != -1) {
        g[i].push_back(Edge(j, a));
        g[j].push_back(Edge(i, a));
      }
    }
  }
  std::cout << prim(g) << std::endl;

  return 0;
}

C++: #include <bits/stdc++.h>

//{ START
using namespace std;
#define int int64_t
#define rep(i, a, n) for (int i = (a); i < (n); ++i)
#define reps(i, a, n) for (int i = (a); i > (n); --i)
#define arep(i, x) for (auto &&i : (x))
#define irep(i, x) for (auto i = (x).begin(); i != (x).end(); ++i)
//降順はgreater<T>()
#define all(x) (x).begin(), (x).end()
#define rv(s) reverse((s).begin(), (s).end())
//gcd lcmはそのままok
#define gcd(a, b) __gcd(a, b)
#define bits(n) (1 << (n))
#define pcnt(x) __builtin_popcountll(x)
//配列内等要素削除
#define unique(x) (x).erase(unique(x).begin(),(x).end()),(x).end())
#define Fixed(n) fixed << setprecision(n)
//総和
#define sowa(n) ((n) * ((n) + 1)) / 2
#define pb(x, a) (x).push_back(a)
#define fb(x, a) (x).push_front(a)
#define eb(x, a) (x).emplace_back(a)
#define F first
#define S second
#define cauto const auto &
using P = pair<int, int>;
using Graph = vector<vector<P>>;
template <class T> //昇順
using min_heap = priority_queue<T, vector<T>, greater<T>>;
template <class T> //降順
using max_heap = priority_queue<T>;
template <class A, class B>
using umap = unordered_map<A, B>;
template <class A>
using uset = unordered_set<A>;
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) //多次元初期化
{
    std::fill((T *)array, (T *)(array + N), val);
}
template <class T>
bool chmax(T &a, const T &b) //最大値更新 返り値はbool
{
    if (a < b)
    {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
bool chmin(T &a, const T &b) //最小値更新 返り値はbool
{
    if (b < a)
    {
        a = b;
        return 1;
    }
    return 0;
}
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
constexpr int INF = 0x3f3f3f3f;
constexpr int LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr int mod1 = 1e9 + 7;
constexpr int mod2 = 998244353;
//} END

constexpr int MAX_V = 10010;
int cost[MAX_V][MAX_V]; //d[u][v]は辺e=(u,v)のコスト,(存在しないときはINF),d[i][i]=0
int mincost[MAX_V];     //集合xから辺の最小コスト
bool used[MAX_V];       //頂点Iがxに含まれているか
int V;             //頂点数

int prim()
{
    fill(mincost, mincost + V, INF);
    fill(used, used + V, false);
    mincost[0] = 0;
    int res = 0;
    while (true)
    {
        int v = -1;
        //xに属さない頂点のうちxからの辺のコストが最小になる頂点を探す
        rep(u, 0, V)
        {
            if (!used[u] && (v == -1 || mincost[u] < mincost[v]))
                v = u;
        }
        if (v == -1)
            break;
        used[v] = true;    //頂点vをxに追加
        res += mincost[v]; //辺のコストを加える
        rep(u, 0, V) if (cost[v][u] != -1) chmin(mincost[u], cost[v][u]);
    }
    return res;
}

signed main()
{
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    cin >> V;
    rep(i, 0, V) rep(j, 0, V) cin >> cost[i][j];

    cout<<prim()<<'\n';
}

C++: #include <iostream>
#include <list>
#include <utility>
using namespace std;
#define MAXN 100
#define MAXW 2001

int main(){
    int weight[MAXN][MAXN];
    int n; cin >> n;
    for(int i=0; i<n; i++){
        for(int j=0; j<n; j++){
            cin >> weight[i][j];
        }
    }
    
    list<int> MST;
    MST.push_back(0);
    list<int> nonMST;
    for(int i=1; i<n; i++) nonMST.push_back(i);
    
    int weightSum = 0;
    while(!nonMST.empty()){
        int tmpv;
        int tmpWeight = MAXW;
        for(list<int>::iterator it=MST.begin(); it!=MST.end(); it++){
            for(list<int>::iterator it2=nonMST.begin(); it2!=nonMST.end(); it2++){
                if (weight[*it][*it2] < tmpWeight && weight[*it][*it2] != -1){
                    //cout << "tmpWeight update with " << *it2 << endl;
                    tmpWeight = weight[*it][*it2];
                    tmpv = *it2;
                }
            }
        }
        //cout << "MST pushback :" << tmpv << endl; 
        MST.push_back(tmpv);
        nonMST.remove(tmpv);
        weightSum += tmpWeight;
        /*for(list<int>::iterator it=MST.begin(); it!=MST.end(); it++){
            cout << *it << " ";
        }
        cout << endl;
        for(list<int>::iterator it=nonMST.begin(); it!=nonMST.end(); it++){
            cout << *it << " ";
        }
        cout << endl;*/
    }
    
    cout << weightSum << endl;
}