#include <bits/stdc++.h> using namespace std; int n, m, v, k, ans, fa[10000001]; struct node//定义结构体存图 { int x, y, z;//z表示x连y的权值 }stu[100001]; int find(int x)//并查集 { if(x != fa[x]) { fa[x] = find(fa[x]); } return fa[x]; }//查找 void unity(int x, int y) { int r1 = find(x); int r2 = find(y); fa[r1] = r2; }//合并 bool cmp(node a, node b)//从小到大结构体排序 { return a.z < b.z; } int main() { scanf("%d", &n); for(int i = 1; i <= n; i++) { fa[i] = i;//并查集初始化 } for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { scanf("%d", &v); if(j > i)//邻接矩阵上下对称,存一半就行了 { m++; stu[m].x = i; stu[m].y = j; stu[m].z = v; } } } sort(stu + 1, stu + m + 1, cmp);//排序 for(int i = 1; i <= m; i++) { if(find(stu[i].x) != find(stu[i].y)) { ans += stu[i].z;//加上最小生成树中边的权值 unity(stu[i].x, stu[i].y);//连接起来 k++;//记录边数 if(k == n - 1)//n - 1条边就行了 { printf("%d", ans); return 0; } } } return 0; }