还是畅通工程

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 51751    Accepted Submission(s): 23482

Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在1行里输出最小的公路总长度。
Sample Input
31 2 11 3 22 3 441 2 11 3 41 4 12 3 32 4 23 4 50
Sample Output
35

Hint

Hint

Huge input, scanf is recommended.

Source
浙大计算机研究生复试上机考试-2006年


问题链接:HDU1233 还是畅通工程。

问题描述:参见上文。

问题分析

  这是一个最小生成树的为问题,解决的算法有Kruskal(克鲁斯卡尔)算法和Prim(普里姆)算法。

程序说明

本程序使用Kruskal算法实现。有关最小生成树的问题,使用克鲁斯卡尔算法更具有优势,只需要对所有的边进行排序后处理一遍即可。程序中使用了并查集,用来判定加入一条边后会不会产生循环。程序中,图采用边列表的方式存储,按边的权从小到大顺序放在优先队列中,省去了排序。

需要注意的是,优先队列申明的位置,以及它和结束条件(“count == n - 1”)的配合。对于每一个测试用例,开始是优先队列应该是空的。

代码不够简洁,又写了一个简洁版。

AC的C++语言程序(简洁版)如下:

/* HDU1233 还是畅通工程 */#include <iostream>
#include <queue>
#include <stdio.h>using namespace std;const int N = 100;
int f[N + 1];void UFInit(int n)
{for(int i = 1; i <=n; i++)f[i] = i;
}int Find(int a) {return a == f[a] ? a : f[a] = Find(f[a]);
}bool Union(int a, int b)
{a = Find(a);b = Find(b);if (a != b) {f[a] = b;return true;} elsereturn false;
}struct edge {int src, dest, cost;bool operator < (const edge& n) const {return cost > n.cost;}
};int main()
{edge e;int n, m;while(scanf("%d", &n) != EOF && n) {priority_queue<edge> q;     // 优先队列,用于存储边列表UFInit(n);m = n * (n-1) / 2;// 构建优先队列while(m--) {scanf("%d%d%d", &e.src, &e.dest, &e.cost);q.push(e);}// Kruskal算法:获得最小生成树int ans=0, count=0;while(!q.empty()) {e = q.top();q.pop();if(Union(e.src, e.dest)) {count++;ans += e.cost;}if(count == n - 1)break;}// 输出结果printf("%d\n", ans);}return 0;
}

AC的C++语言程序如下:

/* HDU1233 还是畅通工程 */#include <iostream>
#include <queue>
#include <cstdio>using namespace std;const int MAXN = 100;// 并查集
int v[MAXN+1];
class UF {int length;
public:UF() {}// 压缩int Find(int x) {if(x == v[x])return x;elsereturn v[x] = Find(v[x]);}bool Union(int x, int y) {x = Find(x);y = Find(y);if(x == y)return false;else {v[x] = y;return true;}}// 唯一树根判定连通性bool isconnect() {int root = -1;for( int i=1 ; i<=length ; i++ )if(root == -1)root = Find(i);elseif(Find(i) != root)return false;return true;}void reset(int n) {length = n;for(int i=0; i<=n; i++)v[i] = i;}
};struct edge {int src, dest, cost;bool operator < (const edge& n) const {return cost > n.cost;}
};int main()
{UF uf;edge e;int n, m;while(scanf("%d", &n) != EOF && n) {priority_queue<edge> q;     // 优先队列,用于存储边列表uf.reset(n);m = n * (n-1) / 2;// 构建优先队列while(m--) {scanf("%d%d%d", &e.src, &e.dest, &e.cost);q.push(e);}// Kruskal算法:获得最小生成树int ans=0, count=0;while(!q.empty()) {e = q.top();q.pop();if(uf.Union(e.src, e.dest)) {count++;ans += e.cost;}if(count == n - 1)break;}// 结果printf("%d\n", ans);}return 0;
}

HDU1233 还是畅通工程【Kruskal算法+并查集】相关推荐

  1. hdu 1233 还是畅通工程 Kruskal 最小生成树 并查集

    题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1233 模板题,kruskal求最小生成树. 并查集是个好东西啊  就是注意一点 输入边的信息时,角标 ...

  2. UVA10034 Freckles【Kruskal算法+并查集】

    In an episode of the Dick Van Dyke show, little Richie connects the freckles on his Dad's back to fo ...

  3. HDU1875 畅通工程再续【Kruskal算法+并查集】

    畅通工程再续 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  4. HDU1863 畅通工程【Kruskal算法+并查集】

    畅通工程 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  5. HDOJ 1863畅通工程(最小生成树kruskal算法并查集实现)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1863 最小生成树kruskal算法:http://www.zhuoda.org/irini/78592.h ...

  6. 还是畅通工程(1233 并查集+kruskal)

    还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  7. 最小生成树kruskal算法并查集版 C语言实现

    今天数据结构课讲了最小生成树的Kruskal算法和Prim算法,不过都只是概念,可能是怕他们听不懂吧,反正算法实现一概不讲...囧 下午抱着<算法导论>跑去图书馆看Kruskal算法,发现 ...

  8. 最小生成树KrusKal算法(并查集)

    洛谷p1111链接 克鲁斯卡尔算法的思路就是由森林变成树的过程,其中最主要的就是贪心和并查集的应用. 我们知道链接n个点需要n-1条边,这就满足的最后生成的是一颗树,而不是一个环.在这n-1条边的选择 ...

  9. 最小生成树Kruskal算法+并查集检查连通

    /* 10 6 1 2 6 1 3 1 1 4 5 2 3 5 2 5 3 3 4 5 3 5 6 3 6 4 4 6 2 5 6 6 */// 本例解决最小生成树问题 // 并查集来加快效率 // ...

最新文章

  1. ForkJoinPool---ForkJoinTask
  2. 运维角度浅谈MySQL数据库优化(转自:2018-03-10 李振良 JAVA高级架构)
  3. android 屏蔽home键操作
  4. ROS系统中的多个版本Boost问题
  5. mysql简单常用语句汇总
  6. Linux 设备树知识点
  7. 1909升级卡64_【春节配置推荐】第3期:设计娱乐万元配置推荐、四代升级建议参考...
  8. 第一章 微服务网关 - 入门
  9. 中介者模式php,php设计模式 Mediator (中介者模式)
  10. Linux SSh scp使用【远程文件/目录的传输】
  11. 计算机 图论基础知识,计算机基础知识
  12. Codeforces 439E Devu and Birthday Celebration 容斥
  13. matlab只加盐噪声,我用matlab中的imnoise函数给图像加椒盐噪声为什么产生的噪声不是黑白的?...
  14. oracle中索引的类型,oracle索引类型normal
  15. 微软api的word在线预览
  16. div+css+js实现深圳交互地图
  17. 以《简单易懂》的语言带你搞懂无监督学习算法【附Python代码详解】机器学习系列之K-Means篇
  18. 选课通知 | 北交大《数据分析方法及应用实战》秋季全校选修课简介!
  19. Excise_Oop_abstract Interface
  20. 基于SSM的校园兼职管理系统

热门文章

  1. GIS制图人员的自我修养(2)--制图意识
  2. Bootstrap手风琴菜单
  3. Golang1.8新特性展望及2016发展回顾
  4. cocos2d-x 2.0版本 自适应屏幕分辨率 .
  5. AMFPHP基本安全问题
  6. 学习Java 第 4天 流程控制语句 one大白(●—●)
  7. python编程语言的优缺点_组队学习优秀作业 | Python的发展历史及其前景
  8. php面试题做得差,php面试题,你能解决几个?
  9. mysql1558错误,mysql删除用户错误ERROR 1558解决办法
  10. clone远程代码 在不同电脑上git_Git 如何 clone 远程 非 master 分支的代码