Go: package main

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

// Define disjoint-set forests

type vertexNo int

type vertex struct {
	number vertexNo
	rank int
	parent *vertex
}

func makeSet(number vertexNo) vertex {
	return vertex {
		number: number,
		rank: 0,
		parent: nil,
	}
}

func union(x, y *vertex) *vertex {
	return link(findSet(x), findSet(y))
}

func link(x, y *vertex) *vertex {
	if x.rank > y.rank {
		y.parent = x
		return x
	} else {
		x.parent = y
		if x.rank == y.rank {
			y.rank += 1
		}
		return y
	}
}

func findSet(v *vertex) *vertex {
	if v.parent == nil {
		return v
	}
	v.parent = findSet(v.parent)
	return v.parent
}

// Function to calculate minimum spanning tree

type matrix [][]int

type edge struct {
	one vertexNo
	two vertexNo
	weight int
}

const(
	MAX_VERTICES = 100
)

func newEdgesFromMatrix(matrix matrix) []edge {
	edges := make([]edge, 0, MAX_VERTICES * MAX_VERTICES)

	for i := 0; i < len(matrix); i++ {
		row := matrix[i]
		for j := i; j < len(row); j++ {
			if row[j] >= 0 {
				edge := edge{one: vertexNo(i+1), two: vertexNo(j+1), weight: row[j]}
				edges = append(edges, edge)
			}
		}
	}

	return edges
}

func solve(matrix matrix) int {
	nVertices := len(matrix)

	// initialize vertices
	vertices := make([]vertex, nVertices)
	for i := 0; i < nVertices; i++ {
		vertices[i] = makeSet(vertexNo(i+1))
	}

	// prepare edges sorted in the ascending order of weight
	edges := newEdgesFromMatrix(matrix)
	sort.Slice(edges, func(i, j int) bool {
		return edges[i].weight < edges[j].weight
	})

	unionCount := 0
	weightSum := 0
	for unionCount < nVertices-1 {
		for i := 0; i < len(edges); i++ {
			edge := edges[i]
			v1 := &vertices[edge.one-1]
			v2 := &vertices[edge.two-1]
			rep1 := findSet(v1)
			rep2 := findSet(v2)
			if rep1.number == rep2.number {
				continue
			}
			union(rep1, rep2)
			edges = append(edges[0:i], edges[i+1:]...)
			weightSum += edge.weight
			unionCount++
			break
		}
	}

	return weightSum
}

// main

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

	n, err := nextInt(sc)
	if err != nil {
		panic(err)
	}

	matrix := parseMatrix(n, sc)

	edges := newEdgesFromMatrix(matrix)
	sort.Slice(edges, func(i, j int) bool {
		return edges[i].weight < edges[j].weight
	})

	fmt.Println(solve(matrix))
}

func parseMatrix(n int, sc *bufio.Scanner) [][]int {
	matrix := make([][]int, n)
	for i := 0; i < n; i++ {
		matrix[i] = make([]int, n)
		for j := 0; j < n; j++ {
			x, err := nextInt(sc)
			if err != nil {
				panic(err)
			}
			matrix[i][j] = x
		}
	}
	return matrix
}

func nextText(sc *bufio.Scanner) string {
	sc.Scan()
	return sc.Text()
}

func nextInt(sc *bufio.Scanner) (int, error) {
	return strconv.Atoi(nextText(sc))
}

Python: MAX = 100
INFTY = 1 << 21
WHITE = 0
GRAY = 1
BLACK = 2
d = [INFTY for i in range(n)]
p = [-1 for i in range(n)]
color = [WHITE for i in range(n)]
d[0] = 0

n = int(input())
M = [[map(int, input().split()) for i in range(n)] for j in range(n)]
for i in range(n):
    for j in range(n):
        if (M[i][j] == -1):
            M[i][j] = INFTY

def prim():
    global M, d, p, color
    while(1):
        minv = INFTY
        u = -1
        for i in range(n):
            if (minv > d[i] and color[i] != BLACK):
                u = i
                minv = d[i]
        if (u == 1):
            break
        color[u] = BLACK
        for v in range(n):
            if (color[v] != BLACK and M[u][v] != INFTY):
                if (d[v] > M[u][v]):
                    d[v] = M[u][v]
                    p[v] = u
                    color[v] = GRAY
    
    _sum([M[i][p[i]] for i in range(n) if (p[i] != -1)])

print(prim())

Python: import queue

INFTY=1<<21

#プリム法
def prim(n,EdgeMatrix):

    EdgeList=queue.PriorityQueue() #探索対象の辺
    used=[False]*n #頂点の使用情報

    used[0]=True #0から探索を始める
    LastNode=0 #最新の頂点
    count=1 #つないだ頂点の数
    EdgeSum=0 #重みの合計

    while count<n:

        for i in range(len(EdgeMatrix[LastNode])):
            #探索していない頂点へ辺があればキューに追加
            Edge=EdgeMatrix[LastNode][i]
            if used[Edge[0]]==False:
                EdgeList.put([Edge[1],Edge[0]])

        #探索していない頂点への最も重みの小さい辺を取り出す
        while True:
            minEdge=EdgeList.get()
            if used[minEdge[1]]==False:
                break

        EdgeSum+=minEdge[0] #辺の合計を増やす
        LastNode=minEdge[1] #最新の頂点を更新
        used[minEdge[1]]=True #頂点の使用情報を更新
        count+=1 #つないだ頂点の数を更新

    return EdgeSum


#入力
n=int(input())

#辺の隣接行列
EdgeMatrix=[[] for i in range(n)]
for i in range(n):
    l=list(map(int,input().split()))
    for j in range(n):
        if l[j]!=-1:
            EdgeMatrix[i].append([j,l[j]])
            EdgeMatrix[j].append([i,l[j]])

#最小全域木の重みの総和
print(prim(n,EdgeMatrix))

Python: #minimum spaning tree

n = int(input())
a = [list(map(int, input().split())) for _ in range(n)]
d = [0] + [1e4]*(n-1)
color = [0]*n

# break = 1 ; glay = 2
while 1:
    mincost = pow(10, 4)
    for i in range(n):
        if color[i] != 1 and d[i] < mincost:mincost = d[i];min_key = i
    if mincost == pow(10,4):
        break
    
    color[min_key] = 1
    
    for i in range(n):
        if color[i] != 1 and a[min_key][i] != -1 and d[i] > a[min_key][i]:
            d[i] = a[min_key][i]
            color[i] = 2
#             parent[i] = min_key
print(f"{sum(d)}")