目标:

今天的两道题做法和思路有相同之处,合并在一起学习可以帮助更快的掌握图论中克鲁斯卡尔算法的要点和据具体实现步骤,下面来看看题目:

第一题【口袋的天空】

题目如下
题目背景
小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空。

有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖。

题目描述
给你云朵的个数 N,再给你 M 个关系,表示哪些云朵可以连在一起。

现在小杉要把所有云朵连成 K 个棉花糖,一个棉花糖最少要用掉一朵云,小杉想知道他怎么连,花费的代价最小。

输入格式
第一行有三个数 N,M,K。

接下来 M 行每行三个数 X,Y,L表示 X 云和 Y 云可以通过 L 的代价连在一起。

输出格式
对每组数据输出一行,仅有一个整数,表示最小的代价。

如果怎么连都连不出 K 个棉花糖,请输出 No Answer。

输入输出样例
输入 #1复制
3 1 2
1 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是结束程序即可。

代码实现:

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
int n,m,k;
struct edge{int u,v,w;bool operator <(const edge &a)const{return w<a.w;//将结构体中的权值作为排序对象处理}
}e[1010101];
int f[1000001];
int ecnt=0;
void add(int u,int v,int w){e[++ecnt].u=u;e[ecnt].v=v;e[ecnt].w=w;
}
int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);//寻找共同的起点
}
int main(){cin>>n>>m>>k;for(int i=1;i<=m;i++){int a,b,c;cin>>a>>b>>c;add(a,b,c);//记录数据}for(int i=1;i<=n;i++){f[i]=i;//初始化,让每个点的起点都为每个点本身}int cnt=0,w=0;sort(e+1,e+1+ecnt);//克鲁斯卡尔算法处理for(int i=1;i<=ecnt;i++){int u=getf(e[i].u);int v=getf(e[i].v);if(u!=v){//当两个点没有共同起点的时候,进行加边处理cnt++;//增加边数w+=e[i].w;//记录答案f[u]=v;//同步起点}if(cnt==n-k){//当cnt等于n-k时说明满足题意cout<<w;return 0;}}cout<<"No Answer";
}

第二题 【部落划分】

题目如下

题目描述
聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落之间则经常发生争斗。只是,这一切都成为谜团了——聪聪根本就不知道部落究竟是如何分布的。

不过好消息是,聪聪得到了一份荒岛的地图。地图上标注了 n 个野人居住的地点(可以看作是平面上的坐标)。我们知道,同一个部落的野人总是生活在附近。我们把两个部落的距离,定义为部落中距离最近的那两个居住点的距离。聪聪还获得了一个有意义的信息——这些野人总共被分为了 k 个部落!这真是个好消息。聪聪希望从这些信息里挖掘出所有部落的详细信息。他正在尝试这样一种算法:

对于任意一种部落划分的方法,都能够求出两个部落之间的距离,聪聪希望求出一种部落划分的方法,使靠得最近的两个部落尽可能远离。

例如,下面的左图表示了一个好的划分,而右图则不是。请你编程帮助聪聪解决这个难题。

输入格式
输入文件第一行包含两个整数 n 和 k,分别代表了野人居住点的数量和部落的数量。

接下来 n 行,每行包含两个整数 x,y,描述了一个居住点的坐标。

输出格式
输出一行一个实数,为最优划分时,最近的两个部落的距离,精确到小数点后两位。

输入输出样例
输入 #1复制
4 2
0 0
0 1
1 1
1 0
输出 #1复制
1.00
输入 #2复制
9 3
2 2
2 3
3 2
3 3
3 5
3 6
4 6
6 2
6 3
输出 #2复制
2.00
说明/提示
数据规模与约定
对于 100%100% 的数据,保证 2≤k≤n≤10^3
,0≤x,y≤10^4

思路如下:

和上一题大部分做法一样,但是需要注意题目中的不同之处,本题的cnt需要等于n-k+1时结束。具体原因请仔细读题

代码实现:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int f[10005];
int ecnt=0;
int cnt=0;
int n,k;
struct edge{int u,v;int w;bool operator <(const edge &s)const{return w<s.w;}
}e[1001010];
void add(int u,int v,int w){e[++ecnt].u=u;e[ecnt].w=w;e[ecnt].v=v;
}
double w=0;int ax[101010],ay[100005];
int  js(int x,int y){return (ax[x]-ax[y])*(ax[x]-ax[y])+(ay[x]-ay[y])*(ay[x]-ay[y]);//在此先不进行开方运算,下文统计答案时会开方
}
int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);
}
int main(){cin>>n>>k;for(int i=1;i<=n;i++){cin>>ax[i]>>ay[i];//此题给的是点的坐标所以需要先存下来}    for(int i=1;i<n;i++){for(int j=i+1;j<=n;j++){add(i,j,js(i,j));//函数计算每个点的距离}}for(int i=1;i<=n;i++){f[i]=i;}sort(e+1,e+1+ecnt);//开始处理for(int i=1;i<=ecnt;i++){int u=getf(e[i].u);int v=getf(e[i].v);if(u!=v){cnt++;f[u]=v;w=sqrt(e[i].w);//注意数据类型if(cnt==n-k+1){//注意题目要求printf("%.2lf",w);//注意输出格式return 0;}}}}

总结如下:

这两道题大体上相似之处较多,但是需要注意题目细节和要求,对于不同的数据和要求需要稍加改动,这两道题可以帮助更加深刻的记忆和了解克鲁斯卡尔算法的过程和实现。

【c++图论】【口袋的天空】【部落划分】相关推荐

  1. BZOJ 1821: [JSOI2010]Group 部落划分 Group【MST】

    1821: [JSOI2010]Group 部落划分 Group Time Limit: 10 Sec Memory Limit: 64 MB Description 聪聪研究发现,荒岛野人总是过着群 ...

  2. bzoj 1821: [JSOI2010]Group 部落划分

    1821: [JSOI2010]Group 部落划分 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 2484  Solved: 1165 [Submi ...

  3. 【P1195 口袋的天空】

    P1195 口袋的天空 口袋的天空 题目背景 题目描述 输入格式 输出格式 样例 #1 样例输入 #1 样例输出 #1 提示 题意及分析 放代码 口袋的天空 题目背景 小杉坐在教室里,透过口袋一样的窗 ...

  4. 最小生成树——洛谷并查集、口袋的天空

    最小生成树--并查集 简单模板题-洛谷3367并查集 题目描述 如题,现在有一个并查集,你需要完成合并和查询操作. 输入格式 第一行包含两个整数 N,MN,M ,表示共有 NN 个元素和 MM 个操作 ...

  5. 张韶涵《口袋的天空》小提琴谱片段

    很喜欢张韶涵<口袋的天空>这首歌,每次听感觉都很好.中间有一段小提琴的乐曲,听着特别感人. 找了很久的<口袋的天空>的小提琴谱,一直没有找到,终于有一次找到了这段小提琴谱,2分 ...

  6. P1111 修复公路P1195 口袋的天空

    目录 P1111 修复公路 P1195 口袋的天空 P1111 修复公路 题目链接:https://www.luogu.com.cn/problem/P1111 标签:并查集,最小生成树 思路:本题用 ...

  7. P1195 口袋的天空-Kruskal(优先队列+并查集)

    口袋的天空 题目背景 小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空. 有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖. 题目描述 给你云朵的个数 N N N,再给你 M M ...

  8. Acwing 2382. 部落划分

    题目描述: 聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落之间则经常发生争斗. 只是,这一切都成为谜团了- ...

  9. C++之路进阶——bzoj1821(部落划分)

    F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser   hyxzc Logout 捐赠本站 Notice:1:由于本OJ ...

最新文章

  1. 2022-2028年中国房地产金融行业投资分析及前景预测报告
  2. S9306开启web功能!
  3. Enhancement spot 增强点简介
  4. IDEA 集成Lombok 插件-安装插件
  5. aerials标准测试图像_Python 图像读写谁最快?不信就比一比
  6. mysql 查询商品列表 显示tag_让前台页面商品列表显示后台数据库中的商品
  7. html css网页布局实例简单,Div+CSS网页布局项目实战一(含设计图、HTML和CSS源文件)...
  8. springboot 多数据源_SpringBoot整合多数据源的巨坑一
  9. windows 7中的windows键相关的快捷键
  10. WebView学习笔记
  11. vrrp协议_Keepalived的高可用基石 - VRRP协议
  12. SpannableString与SpannableStringBuilder
  13. Migrate Project to Gradle? This project does not use the Gradle build system
  14. python 实现冒泡排序
  15. ubuntu20.04 推荐翻译软件
  16. linux防火墙查看状态firewall、iptable
  17. bzoj2037 Sue的小球(区间dp,考虑到对未来的贡献)
  18. Mybatis| Bug合集
  19. 什么是TMD格式?TDM格式详细介绍
  20. 官网下载git缓慢问题

热门文章

  1. GenOS linux 安装 JDK jdk-6u45-linux-x64.bin
  2. 【文献阅读】SoccerNet: A Scalable Dataset for Action Spotting in Soccer Videos
  3. 鸿蒙系统适配微信,微信鸿蒙版本下载-微信鸿蒙系统app官方下载 v8.0.3-手游之家...
  4. 零基础小白必备PS抠图技巧
  5. .spring 知识点总结
  6. 12306采用Pivotal GemFire分布式解决方案 解决尖峰高流量并发问题
  7. 2016年-2021年【总目录】
  8. 数据库的“读现象”浅析
  9. 淘宝平台自研系统入驻流程
  10. Down友庆新年,下载中心新版分享达人排行赛开始!【已结束】