Kruskal算法思想:贪心选边,用并查集维护点集。
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 using namespace std; 7 const int maxn = 5000 + 10; 8 int n, m, f[maxn], sum = 0, tot = 0; 9 struct Edge{ 10 int from, to, w; 11 bool operator < (const Edge& ths) const { 12 return w < ths.w; 13 } 14 }adj[maxn]; 15 int findset(int x){ 16 return x == f[x] ? x : f[x] = findset(f[x]); 17 } 18 void Kruskal(){ 19 sort(adj, adj + m); 20 for(int i = 0; i < m; i ++){ 21 int f1 = findset(adj[i].from), f2 = findset(adj[i].to); 22 if(f1 != f2){ 23 f[f2] = f1; 24 sum += adj[i].w; 25 tot ++; 26 if(tot == m) break; 27 } 28 } 29 return ; 30 } 31 void read(int &x){ 32 x = 0; int sig = 1; char ch = getchar(); 33 while(!isdigit(ch)) { if(ch == ‘-‘) sig = -1; ch = getchar(); } 34 while(isdigit(ch)) x = 10 * x + ch - ‘0‘, ch = getchar(); 35 x *= sig; return ; 36 } 37 void init(){ 38 read(n); m = n * (n - 1) * 0.5; 39 for(int i = 0; i < n; i ++) f[i] = i; 40 for(int i = 0; i < m; i ++) 41 read(adj[i].from), read(adj[i].to), read(adj[i].w); 42 return ; 43 } 44 void work(){ 45 Kruskal(); 46 return ; 47 } 48 void print(){ 49 printf("%d\n", sum); 50 return ; 51 } 52 int main(){ 53 init(); 54 work(); 55 print(); 56 return 0; 57 }
时间: 2024-10-05 16:58:07