#include using namespace std; const int N = 110, M = 10010; const int INF = 0x3f3f3f3f; int n, m; // n个节点,m条边 // Kruskal用到的结构体 struct Node { int a, b, c; bool const operator<(const Node &t) const { return c < t.c; // 边权小的在前 } } edge[M]; // 数组长度为是边数 // 并查集 int p[N]; int find(int x) { if (p[x] != x) p[x] = find(p[x]); return p[x]; } int res; // 最小生成树的权值和 int cnt; // 最小生成树的结点数 // Kruskal算法 void kruskal() { // 1、按边权由小到大排序 sort(edge, edge + m); // 2、并查集初始化 for (int i = 1; i <= n; i++) p[i] = i; // 3、迭代m次 for (int i = 0; i < m; i++) { int a = edge[i].a, b = edge[i].b, c = edge[i].c; a = find(a), b = find(b); if (a != b) p[a] = b, res += c, cnt++; // cnt是指已经连接上边的数量 } // 4、特判是不是不连通 if (cnt < n - 1) res = INF; } int main() { cin >> n; // 邻接矩阵 for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { int c; cin >> c; edge[m++] = {i, j, c}; // 加入当前的边 } kruskal(); cout << res << endl; return 0; }