http://acm.hdu.edu.cn/showproblem.php?pid=1233
//结构体做法
#include <stdio.h> #include <stdlib.h> #include <string.h> int p[101],sum,num; //p为并查集 struct edge//图的结构体 { int sv,ev,w;//起始边,终边,权值。 }; struct edge e[10000];//必须开到大于(n*n-1)/2,否则必然RE。。。 int comp(const void *a,const void *b){ return (*(struct edge*)a).w > (*(struct edge*)b).w ?1:-1; } int find(int x){//并查集find函数 return p[x] == x ? x : (p[x] = find(p[x]));//压缩路径 } void merge(int x,int y,int w){//并查集merge函数 x = find(x); y = find(y); if(x != y){ p[x] = y; sum += w; num++; } } int main(){ int n,m,i; while(scanf("%d",&n)==1 && n != 0) { sum = 0; num = 1; m = n*(n-1)/2; for(i = 1;i <= n;i ++) p[i] = i;//初始化并查集 for(i = 0;i < m;i ++){ scanf("%d %d %d",&e[i].sv,&e[i].ev,&e[i].w); } qsort(e,m,sizeof(e[0]),comp);//调用结构体快排 for(i = 0; i < m; i++){ merge(e[i].sv,e[i].ev,e[i].w; if(num == n) break; } printf("%d\n",sum); } return 0; }
//直接数组
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXN 6000 int u[MAXN], v[MAXN], w[MAXN], r[MAXN], p[MAXN]; int cmp(const void *a, const void *b){ int x = *(int *)a, y = *(int *)b; return w[x] - w[y]; } int find(int x){return p[x] == x ? x : (p[x] = find(p[x]));} int Kruskal(int n, int m){ int ans = 0, i; for(i=0; i<n; i++) p[i] = i;//初始化并查集 for(i=0; i<m; i++) r[i] = i;//初始化边号 qsort(r, m, sizeof(r[0]), cmp); for(i=0; i<m; i++){ int e = r[i]; int x = find(u[e]); int y = find(v[e]); if(x != y) {ans += w[e]; p[x] = y;} } return ans; } int main(){ int n, m, i; while(scanf("%d", &n) == 1 && n != 0){ m = n*(n-1)/2; for(i=0; i<m; i++){ scanf("%d %d %d", &u[i], &v[i], &w[i]); u[i]--; v[i]--;//从零开始编号 } printf("%d\n", Kruskal(n, m)); } return 0; } //如果是从1开始编号 只需要注释掉 //u[i]--; v[i]--; //并且把for(i=0; i<n; i++) p[i] = i;//初始化并查集 //改成for(i=1; i<=n; i++) p[i] = i;//初始化并查集