题目链接:http://code.hdu.edu.cn/showproblem.php?pid=1233

并查集的运用, 实质就是求最小生成树。先对所有的村庄距离从小到大排序,然后判断村庄之间是否属于同一集合,不是则将距离相加。属于同一集合,说明村庄连成了环,就不符合树的定义了。这样扫描下来,就求得最小生成树了。

要特别注意的是,数组越界问题。这个得益于Dwylkz的指点。由于村庄最多假设为100,为了防止边数越界,数组应该开到100 * 100 (10000)左右。

 #include <iostream>
#include <algorithm>
using namespace std; const int maxn = + ; // 100个村庄边数最多为10000
struct sets
{
int v1, v2; // v1,v2分别表示村庄1和村庄2
int value; // 保存两村庄间的距离
} test[maxn]; int set[maxn]; // 保存集合中的代表 int cmp(sets a, sets b)
{
return a.value < b.value;
} int find(int x)
{
return x == set[x] ? x : find(set[x]);
} int main()
{
int a, b, i, n, cnt;
while (scanf("%d", &n) != EOF && n)
{
for (i = ; i <= n; i++)
{
set[i] = i; // 初始化为n个不相交的集合
}
int len = n * (n-) / ; // 输入的行数
for (i = ; i < len; i++)
{
scanf("%d%d%d", &test[i].v1, &test[i].v2, &test[i].value);
}
sort(test, test+len, cmp); // 对距离从小到大排序
for (cnt = i = ; i < len; i++)
{
a = find(test[i].v1);
b = find(test[i].v2);
if (a != b) // 不属于同一集合,则将距离相加,这个已保证能得到最小生成树
{
set[a] = b;
cnt += test[i].value;
}
}
printf("%d\n", cnt);
}
return ;
}

最新文章

  1. 多线程同步工具——LockSupport
  2. iis日志查看
  3. linux下搭建php的集成环境
  4. 深入理解JS的delete
  5. nVivo highlight code中的文本
  6. IE6、7绝对定位层被遮挡的原因(主要是父层决定的)
  7. 手把手教你在Windows下使用MinGW编译libav(参考libx264的编入)
  8. js实现windows扫雷(jquery)
  9. Android Intent的几种使用方法全面总结
  10. Linux C语言遍历目录结构
  11. MySql 日期转字符串
  12. linux路由表配置
  13. Harris角点检测算原理
  14. MAC vim安装gruvbox主题
  15. 记一次Java Core Dump分析过程
  16. Java输入输出小结
  17. C++学习 内存模型和名称空间
  18. 多张报表导出到一个多sheet页excel
  19. Bing词典vs有道词典比对测试报告
  20. Java CST格式字符串转换成Date类型的数据

热门文章

  1. 【Gym 100015A】Another Rock-Paper-Scissors Problem
  2. 与Java Web Service相关的若干概念(JAX-WS,JAX-RS)
  3. PL/0编译器(java version)&ndash;Praser.java
  4. linux在线学习
  5. Activator.CreateInstance 反射实例化对象
  6. C++标准转换运算符reinterpret_cast
  7. Matalab IFS分形算法
  8. dao、domain、service、web、vo、Model这些层的功能是什么
  9. GTP V0 和 GTP V1
  10. &lt;转&gt;Npoi导入导出Excel操作&lt;载&gt;