题意:给一个无向图的邻接矩阵,求最小生成树。
解法:Kruskal算法。把边按边权排序,从小到大插入生成树中,如果一个边的两个点都在生成树中则不插入,用并查集维护。
代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include<time.h> #include<stdlib.h> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #define LL long long using namespace std; struct node { int u, v; int num; bool operator < (const node & tmp) const { return num < tmp.num; } }edge[10005]; int father[105]; void init() { for(int i = 0; i < 105; i++) father[i] = i; } int Find(int x) { return father[x] == x ? father[x] : father[x] = Find(father[x]); } bool Union(int a, int b) { int c = Find(a), d = Find(b); if(c == d) return false; father[c] = d; return true; } int main() { int n; while(~scanf("%d", &n)) { init(); int cnt = 0; for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) { int x; scanf("%d", &x); if(j > i) { edge[cnt].u = i; edge[cnt].v = j; edge[cnt++].num = x; } } sort(edge, edge + cnt); LL ans = 0; for(int i = 0; i < cnt; i++) { if(Union(edge[i].u, edge[i].v)) ans += edge[i].num; } printf("%lld ", ans); } return 0; }