【c++ 图论例题学习】【口袋的天空】【部落划分】
目标:
今天的两道题做法和思路有相同之处,合并在一起学习可以帮助更快的掌握图论中克鲁斯卡尔算法的要点和据具体实现步骤,下面来看看题目:
第一题【口袋的天空】
题目如下题目背景小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空。
有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖。
题目描述给你云朵的个数 N,再给你 M 个关系,表示哪些云朵可以连在一起。
现在小杉要把所有云朵连成 K 个棉花糖,一个棉花糖最少要用掉一朵云,小杉想知道他怎么连,花费的代价最小。
输入格式第一行有三个数 N,M,K。
接下来 M 行每行三个数 X,Y,L 表示 X 云和 Y 云可以通过 L 的代价连在一起。
输出格式对每组数据输出一行,仅有一个整数,表示最小的代价。
如果怎么连都连不出 K 个棉花糖,请输出 No Answer。
输入输出样例输入 #1 复制 3 1 21 2 1 输出 #1 复制 1 说明/提示对于 30% 的数据,1≤N≤100,1≤M≤10 ^3
对于 100%100% 的数据,1≤N≤10^3,1≤M≤10 ^4,1≤K≤10,1≤X,Y≤N,0≤L<10^4
思路:
由于题目中说需要连接出 k 个棉花糖,所以在处理数据的时候特判一下,记录下输入内容然后克鲁斯卡尔算法进行处理,因为有 n 个云,要连成 k 个棉花糖,所以当边数等于 n-k 是结束程序即可。
代码实现:
第二题 【部落划分】
题目如下
题目描述聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落之间则经常发生争斗。只是,这一切都成为谜团了——聪聪根本就不知道部落究竟是如何分布的。
不过好消息是,聪聪得到了一份荒岛的地图。地图上标注了 n 个野人居住的地点(可以看作是平面上的坐标)。我们知道,同一个部落的野人总是生活在附近。我们把两个部落的距离,定义为部落中距离最近的那两个居住点的距离。聪聪还获得了一个有意义的信息——这些野人总共被分为了 k 个部落!这真是个好消息。聪聪希望从这些信息里挖掘出所有部落的详细信息。他正在尝试这样一种算法:
对于任意一种部落划分的方法,都能够求出两个部落之间的距离,聪聪希望求出一种部落划分的方法,使靠得最近的两个部落尽可能远离。
例如,下面的左图表示了一个好的划分,而右图则不是。请你编程帮助聪聪解决这个难题。
输入格式输入文件第一行包含两个整数 n 和 k,分别代表了野人居住点的数量和部落的数量。
接下来 n 行,每行包含两个整数 x,y,描述了一个居住点的坐标。
输出格式输出一行一个实数,为最优划分时,最近的两个部落的距离,精确到小数点后两位。
输入输出样例输入 #1 复制 4 20 00 11 11 0 输出 #1 复制 1.00 输入 #2 复制 9 32 22 33 23 33 53 64 66 26 3 输出 #2 复制 2.00 说明/提示数据规模与约定对于 100%100% 的数据,保证 2≤k≤n≤10^3,0≤x,y≤10^4
思路如下:
和上一题大部分做法一样,但是需要注意题目中的不同之处,本题的 cnt 需要等于 n-k+1 时结束。具体原因请仔细读题
代码实现:
总结如下:
这两道题大体上相似之处较多,但是需要注意题目细节和要求,对于不同的数据和要求需要稍加改动,这两道题可以帮助更加深刻的记忆和了解克鲁斯卡尔算法的过程和实现。
版权声明: 本文为 InfoQ 作者【贤鱼很忙】的原创文章。
原文链接:【http://xie.infoq.cn/article/ba906ed63c92819dabc8a15a7】。未经作者许可,禁止转载。
评论