最小生成树。
Kruskal 算法:其中应用并查集。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 5 using namespace std; 6 7 typedef struct 8 { 9 int a, b; 10 int d; 11 }node; 12 13 node w[5002]; 14 int set[102]; 15 16 int cmp(const void *a, const void *b) 17 { 18 node *x=(node *)a; 19 node *y=(node *)b; 20 return x->d - y->d; 21 } 22 23 int find(int n) 24 { 25 int x=n; 26 if (x != set[x]) 27 set[x]=find(set[x]); 28 return set[x]; 29 } 30 31 int merge(int a, int b) 32 { 33 int x=find(a); 34 int y=find(b); 35 if (x == y) 36 return 0; 37 set[x]=y; 38 return 1; 39 } 40 41 int main() 42 { 43 int i, n, cnt, sum; 44 while(scanf("%d", &n) && n) 45 { 46 for (i=1; i<=n; i++) 47 set[i]=i; 48 for (i=0; i<n*(n-1)/2; i++) 49 scanf("%d%d%d", &w[i].a, &w[i].b, &w[i].d); 50 qsort(w, n*(n-1)/2, sizeof(w[0]), cmp); 51 cnt=1; 52 sum=0; 53 for (i=0; cnt<n; i++) 54 { 55 if (merge(w[i].a, w[i].b)) 56 { 57 cnt++; 58 sum+=w[i].d; 59 } 60 } 61 cout << sum << endl; 62 } 63 return 0; 64 }
Prim 算法:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 5 using namespace std; 6 7 int map[102][102]; 8 9 int prim(int n) 10 { 11 int i, j, min; 12 int d[102], pos; //d[] 记录从已知到未知点集路径权值 13 int vis[102], sum=0; //vis[] 标记访问 14 memset(vis, 0, sizeof(vis)); 15 for (i=1; i<=n; i++) 16 { 17 d[i]=map[1][i]; 18 } 19 vis[1]=1; 20 for (i=1; i<n; i++) 21 { 22 min=100000; 23 for (j=1; j<=n; j++) //扫描找到最小 从已知到未知 节点的权值 并标记位置 24 { 25 if (vis[j] == 0 && min > d[j]) 26 { 27 pos=j; 28 min=d[j]; 29 } 30 } 31 sum+=min; 32 vis[pos]=1; 33 for (j=2; j<=n; j++) // 更新 权值数组d[] 34 { 35 if (vis[j] == 0 && d[j] > map[pos][j]) 36 d[j]=map[pos][j]; 37 } 38 } 39 return sum; 40 } 41 42 int main() 43 { 44 int n, i, j, a, b, d; 45 while(scanf("%d", &n) && n) 46 { 47 for (i=1; i<=n; i++) 48 for (j=1; j<=n; j++) 49 map[i][j]=100000; 50 for (i=1; i<=n; i++) 51 map[i][i]=0; 52 for (i=1; i<=n*(n-1)/2; i++) 53 { 54 scanf("%d%d%d", &a, &b, &d); 55 map[b][a]=map[a][b]=d; 56 } 57 printf("%d\n", prim(n)); 58 } 59 return 0; 60 }