专题四1004
2016-06-17 22:04
369 查看
题目大意:
谋生的统计表中列出了任意两个村庄见的距离,为了实现全省两个村庄间都可以实现公路交通,现在要修路,要求编程输出在满足任意两个村庄都是可达的前提下,需要修建的最短的公路长度。
输入:
测试实例包括多个。每个实例的第一行输入一个正整数N,代表村庄的数目,然后接下来的m=N*(N-1)/2行每行包括3个整数,前两个整数代表两个村庄的编号,然后第3个整数代表两个村庄的距离。当输入的N为0时,程序结束。
输出:
每行输出一个整数,代表每个实例的结果。
解题思路:
并查集问题。首先定义一个结构体变量Road,属性包括两个村庄的编号以及这两个村庄见的距离,定义一个Road类型的数组road[110],题目要求输出最短路径,输入信息完毕后,将所有路径按照路径长度从小到大的顺序排列起来,用一个整形数组P[100]存储节点,并初始化,代表刚开始时各个节点之间没有关联,然后一个for循环,从1到m,对于每条路径进行合并,若findx(x)==findx(y),说明两个节点之前已经联通;若findx(x)!=findx(y),说明两个节点之间无关联,此时加上这两个节点间的距离,然后将这两个节点合并,代表两个节点间现已联通,最后得到的totallength即为答案,因为我们事先已经把路径按照从小到大的顺序排列,所以这样得到的答案一定是最短的。
感想:
关于图的问题感觉并不难,其实说白了就是一个并查集的使用,只是现在感觉到图这个东西真的太重要了,好几门学科都涉及到了图。
代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
struct Road
{
int x;
int y;
int length;
};
Road road[200];
int p[100];
int TotalLength;
bool Judge(Road &r1, Road &r2)
{
return r1.length < r2.length;
}
int findx(int x)
{
int r = x;
if (p[x] == r)
return r;
else
return findx(p[x]);
}
void merge(int x, int y,int z)
{
int fx, fy;
fx = findx(x);
fy = findx(y);
if (fx != fy)
{
p[fx] = fy;
TotalLength += road[z].length;
}
}
int main()
{
int n, m;
while (cin >> n)
{
TotalLength = 0;
if (n == 0)
break;
m = n*(n - 1) / 2;
for (int i = 1; i <= n; i++)
p[i] = i;
for (int i = 1; i <= m; i++)
cin >> road[i].x >> road[i].y >> road[i].length;
sort(road + 1, road + 1 + m, Judge);
for (int i = 1; i <= m; i++)
merge(road[i].x, road[i].y, i);
cout << TotalLength << endl;
}
return 0;
}
谋生的统计表中列出了任意两个村庄见的距离,为了实现全省两个村庄间都可以实现公路交通,现在要修路,要求编程输出在满足任意两个村庄都是可达的前提下,需要修建的最短的公路长度。
输入:
测试实例包括多个。每个实例的第一行输入一个正整数N,代表村庄的数目,然后接下来的m=N*(N-1)/2行每行包括3个整数,前两个整数代表两个村庄的编号,然后第3个整数代表两个村庄的距离。当输入的N为0时,程序结束。
输出:
每行输出一个整数,代表每个实例的结果。
解题思路:
并查集问题。首先定义一个结构体变量Road,属性包括两个村庄的编号以及这两个村庄见的距离,定义一个Road类型的数组road[110],题目要求输出最短路径,输入信息完毕后,将所有路径按照路径长度从小到大的顺序排列起来,用一个整形数组P[100]存储节点,并初始化,代表刚开始时各个节点之间没有关联,然后一个for循环,从1到m,对于每条路径进行合并,若findx(x)==findx(y),说明两个节点之前已经联通;若findx(x)!=findx(y),说明两个节点之间无关联,此时加上这两个节点间的距离,然后将这两个节点合并,代表两个节点间现已联通,最后得到的totallength即为答案,因为我们事先已经把路径按照从小到大的顺序排列,所以这样得到的答案一定是最短的。
感想:
关于图的问题感觉并不难,其实说白了就是一个并查集的使用,只是现在感觉到图这个东西真的太重要了,好几门学科都涉及到了图。
代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
struct Road
{
int x;
int y;
int length;
};
Road road[200];
int p[100];
int TotalLength;
bool Judge(Road &r1, Road &r2)
{
return r1.length < r2.length;
}
int findx(int x)
{
int r = x;
if (p[x] == r)
return r;
else
return findx(p[x]);
}
void merge(int x, int y,int z)
{
int fx, fy;
fx = findx(x);
fy = findx(y);
if (fx != fy)
{
p[fx] = fy;
TotalLength += road[z].length;
}
}
int main()
{
int n, m;
while (cin >> n)
{
TotalLength = 0;
if (n == 0)
break;
m = n*(n - 1) / 2;
for (int i = 1; i <= n; i++)
p[i] = i;
for (int i = 1; i <= m; i++)
cin >> road[i].x >> road[i].y >> road[i].length;
sort(road + 1, road + 1 + m, Judge);
for (int i = 1; i <= m; i++)
merge(road[i].x, road[i].y, i);
cout << TotalLength << endl;
}
return 0;
}
相关文章推荐
- Android极光推送之Hello World
- abstract(抽象)修饰符
- 机器学习总结9_未完待续
- 【android】:android设计网站
- 【POJ】2891 Strange Way to Express Integers
- 嵌入式系统通用驱动程序接口及其实现-EERPOM存取位置标准化(视频教学时的同步输入文件)
- 使用struts1回显数据,防重复提交
- 【设计模式】过滤器模式
- 关于MYSQL的一些命令
- 基于C++的简单的FSM实现
- BZOJ3489 A simple rmq problem
- 补c++作业2
- 再次拾回android-修改系统定义的style
- SQLServer附加数据库失败
- 彩电市场竞争格局巨变, 创维“修炼内功”逆势增长
- exit和_exit,atexit的浅析
- 【翻译】Tweepy 3.5.0 Doc (2) Authentication Tutorial
- selenium常用命令之操作页面元素及获取元素内容的事件整理
- java学习笔记之ORM注解
- Deep Learning(深度学习)学习笔记整理系列之(四)