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>
#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;//初始化并查集
//结构体做法
#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;//初始化并查集
相关文章推荐
- HDU1233 还是畅通工程(最小生成树模板题,Prime,kruskal算法)
- HDU1233还是畅通工程(最小生成树 Kruskal算法)
- hdu1233 还是畅通工程(两种基本最小生成树算法)
- Hdu1233-还是畅通工程-【最小生成树】【Kruskal算法】
- hdu1233 还是畅通工程(最小生成树)
- 解题报告之——hdu1233还是畅通工程(最小生成树)
- HDU1233还是畅通工程(最小生成树)
- 【HDU1233】还是畅通工程(最小生成树)
- 【HD 1233】还是畅通工程(最小生成树 Kruskal算法模板题)
- HDU 1233-还是畅通工程(最小生成树)
- hdu1233 还是畅通工程 最小生成树 Prim算法堆优化
- 最小生成树模板题 HDU1233 还是畅通工程
- 杭电OJ——1233 还是畅通工程(最小生成树问题)
- 1233 还是畅通工程(最小生成树)
- hdu1233 还是畅通工程 (kruskal求最小生成树)
- hdu 还是畅通工程 (基础)(最小生成树)(Prim算法 && Kruskal算法)
- hdu 1233 还是畅通工程(最小生成树,kruskal,前向星)
- HDU-1233 还是畅通工程(最小生成树Prim算法)
- poj1258 Agri-Net +hdu 1233 还是畅通工程 (最小生成树Prime算法)
- hdu 还是畅通工程 (基础)(最小生成树)(Prim算法 && Kruskal算法)