#include <stdio.h>
#include <string.h>
#define DEBUG
#ifdef DEBUG
#define debug(...) printf( __VA_ARGS__)
#else
#define debug(...)
#endif
#define N 100
#define MAX_INT 20000000
int graph[N][N];
int dist[N]; /* dist[i]表示顶点i距离已加入集合的最小距离, 如果dist[i]变为-1, 表示顶点i已加入集合 */
int n;
int prim(int u)
{
int i, p, min, total_cost, min_edge;
for (i = 0; i < n; i++) {
dist[i] = MAX_INT;
}
p = u; /* p为选种加入集合的点,初始时为u */
total_cost = 0;
for (;;) {
min = MAX_INT;
min_edge = -1;
debug("顶点%d加入集合\n", p);
dist[p] = -1;
/* 把顶点p加入集合后, 遍历所有未加入集合的顶点, 更新它们的距离, 同时找出距离最小的顶点 */
for (i = 0; i < n; i++) {
if (dist[i] >= 0) { /* 顶点i未加入集合 */
if (graph[p][i] > 0 && graph[p][i] < dist[i]) {
dist[i] = graph[p][i];
debug("更新顶点%d的距离为%d\n", i, dist[i]);
}
if (dist[i] < min) {
min = dist[i];
min_edge = i;
}
}
}
if (min_edge == -1) break;
debug("距离最小的顶点为%d, 长度为%d\n", min_edge, min);
p = min_edge;
total_cost += min;
}
return total_cost;
}
int main()
{
int i, j;
while (scanf("%d", &n) != EOF) {
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
scanf("%d", &graph[i][j]);
}
}
printf("%d\n", prim(0));
}
return 0;
}