您的位置:首页 > 其它

HDU1233还是畅通工程(最小生成树 Kruskal算法)

2013-01-27 20:51 489 查看
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;//初始化并查集
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: