「模拟8.17」star way to heaven(并查集,最小生成树)
80分打法
首先二分最后答案,答案即为r,可看作以每个k为圆心r为半径的圆
我们进行并查集维护,维护相交的圆的边界
最后判断是否存在圆将上下边界覆盖,如有证明不行
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<cmath>
5 #include<algorithm>
6 #include<string>
7 #include<vector>
8 #include<map>
9 #include<set>
10 #define min(a,b) a>b?b:a
11 #define max(a,b) a>b?a:b
12 #define int long long
13 #define MAXN 1000001
14 using namespace std;
15 int fa[MAXN];
16 double l_y[MAXN],r_y[MAXN];
17 int x[MAXN],y[MAXN];
18 int find(int x)
19 {
20 if(fa[x]==x)return fa[x];
21 return fa[x]=find(fa[x]);
22 }
23 bool judge(int xx,int yy,double r)
24 {
25 double deta_x=abs(x[xx]-x[yy]);
26 double deta_y=abs(y[xx]-y[yy]);
27 //printf("deta_x=%lld deta_y=%lld\n",deta_x,deta_y);
28 if((double)deta_x*deta_x+(double)deta_y*deta_y<(2.0*r)*(r*2.0))return 1;
29 return 0;
30 }
31 int n,m,k;
32 bool work(double cir)
33 {
34 for(int i=1;i<=k;++i)fa[i]=i;
35 for(int i=1;i<=k;++i)
36 {
37 l_y[i]=(double)y[i]-cir;r_y[i]=(double)y[i]+cir;
38 }
39 for(int i=1;i<=k;++i)
40 {
41 for(int j=1;j<=k;++j)
42 {
43 //printf("i=%lld j=%lld\n",i,j);
44 int xx=find(i);int yy=find(j);
45 if(xx==yy)continue;
46 if(judge(i,j,cir))
47 {
48 fa[yy]=xx;
49 l_y[yy]=l_y[xx]=min(l_y[yy],l_y[xx]);
50 r_y[yy]=r_y[xx]=max(r_y[yy],r_y[xx]);
51 //printf("l_y[%lld]=%.4lf r_y[%lld]=%.4lf\n",xx,l_y[xx],xx,r_y[xx]);
52 }
53 }
54 }
55 for(int i=1;i<=k;++i)
56 {
57 if(l_y[find(i)]<cir&&r_y[find(i)]>m-cir)
58 {
59 //printf("l_y[%lld]=%.4lf r_y[%lld]=%.4lf\n",find(i),l_y[find(i)],find(i),r_y[find(i)]);
60 return 0;
61 }
62 }
63 return 1;
64 }
65 void second_divided()
66 {
67 double l=0.0,r=m;
68 while(l+0.0000001<r)
69 {
70 double mid=(l+r)/2;
71 //printf("mid=%.4lf\n",mid);
72 if(work(mid))
73 {
74 l=mid;
75 }
76 else r=mid;
77 }
78 if(work(r))printf("%.6lf\n",r);
79 else printf("%.6lf\n",l);
80 }
81 signed main()
82 {
83 scanf("%lld%lld%lld",&n,&m,&k);
84 for(int i=1;i<=k;++i)scanf("%lld%lld",&x[i],&y[i]);
85 second_divided();
86 }
100分
开始是很难看出这是最小生成树,(听说是什么欧几里得最小生成树,非常神奇)
对于最小生成树有几个性质:(自己瞎写的,可能不对)
1.最小生成树包含两点之间路径的最小边
2.最小生成树生成的边和最小
对于此题,我们尽量选边权小的边,构成最小生成树,
选出从上边界到下边界的最大边权,除二既是答案
最小生成树保证了选出这个边后,其他圆只会离他更远,所以正确
另外学习了prim算法
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<cmath>
5 #include<algorithm>
6 #include<string>
7 #include<vector>
8 #include<map>
9 #include<set>
10 #define min(a,b) a>b?b:a
11 #define max(a,b) a>b?a:b
12 #define int long long
13 #define MAXN 1000001
14 using namespace std;
15 double disx[MAXN],disy[MAXN];
16 int n,m,k;
17 double d[MAXN];int vis[MAXN];int fa[MAXN];
18 double poww(double x)
19 {
20 return x*x;
21 }
22 struct no{int to,n;double w;}e[MAXN*2];int head[MAXN],tot;
23 void add(int u,int v,double w)
24 {
25 e[++tot].to=v;e[tot].n=head[u];e[tot].w=w;head[u]=tot;
26 }
27 double cal(int x,int y)
28 {
29 if(x>y)swap(x,y);
30 if(x==k+1&&y==k+2)return (double)m;
31 if(y==k+1)return disy[x];
32 if(y==k+2)return (double)m-disy[x];
33 //printf("cal%.4lf\n",sqrt(poww(disx[x]-disx[y])+poww(disy[x]-disy[y])));
34 return sqrt(poww(disx[x]-disx[y])+poww(disy[x]-disy[y]));
35 }
36 void prim()
37 {
38 memset(vis,0,sizeof(vis));
39 for(int i=1;i<=k+2;++i)d[i]=100000000000.0;
40 d[1]=0;
41 for(int i=1;i<k+2;++i)
42 {
43 double minn=100000000000.0;int x=0;
44 for(int j=1;j<=k+2;++j)
45 {
46 if(!vis[j]&&d[j]<minn)
47 {
48 minn=d[j];x=j;
49 }
50 }
51 vis[x]=1;
52 for(int j=1;j<=k+2;++j)
53 {
54 if(!vis[j])
55 {
56 double dis=cal(x,j);
57 if(dis<d[j])
58 {
59 d[j]=dis;
60 fa[j]=x;
61 //printf("j=%lld x=%lld dis=%.4lf\n",j,x,d[j]);
62 }
63 }
64 }
65 }
66 for(int i=2;i<=k+2;++i)
67 {
68 add(i,fa[i],d[i]);add(fa[i],i,d[i]);
69 //printf("%lld %lld %.4lf\n",fa[i],i,d[i]);
70 }
71 }
72 double ans=0.0;
73 void DFS(int x,double w,int fa)
74 {
75 if(x==k+2){ans=w;return ;}
76 for(int i=head[x];i;i=e[i].n)
77 {
78 int to=e[i].to;
79 if(to==fa)continue;
80 DFS(to,max(w,e[i].w),x);
81 }
82 }
83 signed main()
84 {
85 scanf("%lld%lld%lld",&n,&m,&k);
86 for(int i=1;i<=k;++i)
87 {
88 scanf("%lf%lf",&disx[i],&disy[i]);
89 }
90 prim();
91 DFS(k+1,0,0);
92 printf("%.7lf\n",ans/2);
93 }
「模拟8.17」star way to heaven(并查集,最小生成树)的更多相关文章
- 【刷题】LOJ 6227 「网络流 24 题」最长k可重线段集问题
题目描述 给定平面 \(\text{xoy}\) 上 \(n\) 个开线段组成的集合 \(\text{I}\) ,和一个正整数 \(k\) ,试设计一个算法. 从开线段集合 \(\text{I}\) ...
- LibreOJ #6014. 「网络流 24 题」最长 k 可重区间集
#6014. 「网络流 24 题」最长 k 可重区间集 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 ...
- loj #6014. 「网络流 24 题」最长 k 可重区间集
#6014. 「网络流 24 题」最长 k 可重区间集 题目描述 给定实直线 L LL 上 n nn 个开区间组成的集合 I II,和一个正整数 k kk,试设计一个算法,从开区间集合 I II 中选 ...
- “伏魔”赏金 | WebShell检测之「模拟污点引擎」首次公测,邀你来战!
安全是一个动态的过程,攻防对抗如同在赛博世界里降妖伏魔,其要义是:取彼之长,补己之短.--伏魔引擎的诞生 伏魔引擎挑战赛 注册时间: 2022.01.10 00:00:00 - 2022.01.24 ...
- 「模拟赛20190327」 第二题 DP+决策单调性优化
题目描述 小火车虽然很穷,但是他还是得送礼物给妹子,所以他前往了二次元寻找不需要钱的礼物. 小火车准备玩玩二次元的游戏,游戏当然是在一个二维网格中展开的,网格大小是\(n\times m\)的,某些格 ...
- 「模拟赛20180306」回忆树 memory LCA+KMP+AC自动机+树状数组
题目描述 回忆树是一棵树,树边上有小写字母. 一次回忆是这样的:你想起过往,触及心底--唔,不对,我们要说题目. 这题中我们认为回忆是这样的:给定 \(2\) 个点 \(u,v\) (\(u\) 可能 ...
- 「模拟8.29」chinese(性质)·physics·chemistry(概率期望)
T1 chinese 根据他的问题i*f[i]我们容易联想到,答案其实是每种方案中每个点的贡献为1的加和 我们可以转变问题,每个点在所有方案的贡献 进而其实询问就是1-k的取值,有多少中方案再取个和 ...
- 「模拟8.21」山洞(矩阵优化DP)
暴力: 正解: 考虑循环矩阵,f[i][j]表示从i点到j点的方案数 我们发现n很小,我们预处理出n次的f[i][j] 然后在矩阵快速幂中,我们要从当前的f[i][j]*f[j][k]-->fi ...
- 「模拟8.23」阴阳 DP
对于此题的性质我们考虑DP 分四种情况 黑色块在右侧单调降,单调升 还有在左侧 另外我们这样可能会记重,所以还要将重复记过的也就是边界线是横的和竖的 然后还要将全白全黑加上 1 #include< ...
随机推荐
- ppt技巧一四步法调整PPT
声明:本文所有截图来源于网易云课堂--<和秋叶一起学PPT>,仅作为个人复习之用,特此声明! 常见配色方案 可以从模板或公司logo取色 图片的选择要高清.风格.主题一致
- CRM帮助初创企业降本增效的四个方法
对大部分初创公司来说,只有少数企业能够实现盈利,大部分只能维持盈亏平衡甚至是亏损.这是因为初创企业很难在短时间之内找到稳定的赢利点,而企业面临的风险和投入又是无法预知的.初创企业想要快速盈利,只能降低 ...
- 简单聊聊内存逃逸 | 剑指offer - golang
问题 简单讲讲golang的内存逃逸吗? 解析 什么是内存逃逸 在程序中,每个函数块都会有自己的内存区域用来存自己的局部变量(内存占用少).返回地址.返回值之类的数据,这一块内存区域有特定的结构和寻址 ...
- 『动善时』JMeter基础 — 19、JMeter配置元件【随机变量】
目录 1.随机变量介绍 2.随机变量界面详解 3.随机变量的使用 (1)测试计划内包含的元件 (2)线程组界面内容 (3)随机变量界面内容 (4)HTTP请求界面内容 (5)查看结果 1.随机变量介绍 ...
- Java容器 | 基于源码分析Map集合体系
一.容器之Map集合 集合体系的源码中,Map中的HashMap的设计堪称最经典,涉及数据结构.编程思想.哈希计算等等,在日常开发中对于一些源码的思想进行参考借鉴还是很有必要的. 基础:元素增查删.容 ...
- centos7安装powershell和powercli
poershell github https://github.com/PowerShell/PowerShell/releases 本次采用github下载对应的rpm进行安装 windows下安装 ...
- [PTA]7-3 逆序的三位数 (10分)
要求: 程序每次读入一个正3位数,然后输出按位逆序的数字.注意:当输入的数字含有结尾的0时,输出不应带有前导的0.比如输入700,输出应该是7. 正确思路: 拆分字符串后拼接成整数 1 #includ ...
- [Qt] 打包
步骤: 1.release项目,生成exe文件 2.在命令行中使用windeployqt,将相关文件复制到exe文件所在文件夹 3.用Enigma Virtual Box打包所有文件 参考 https ...
- 【BIGDATA】在Centos上部署ElasticSearch 7.3.2及kibana
一.下载: 首先,下载ElasticSearch和kibana安装包,版本自选,官方下载页https://www.elastic.co/cn/downloads/ 二.版本检查 很重要的一步,要检查C ...
- 联想 lenove 3750 M4服务器更改启动项和管理口IP
联想 lenove 3750 M4服务器更改启动项和管理口IP 注: 因为在机房拍照的原因,再加上工作比较忙:整理成文档的时候有的过程已经忘记了,所以有的步骤可能会缺失,里面的选项都已经用中文方式表达 ...