「模拟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< ...
随机推荐
- java-处理大容量文本文件,行内分格符为TAB的方法
以处理某sql文件为例 源文件中行格式为: 123456 7895433 xxxxx yyyyy zzzzz 行间分隔符为 TAB. 转换完后文件中行的格式为: 123456,7895433,xxx ...
- IO系列测试源码
//IO系列测试源码(需要自取) using System; using System.CodeDom; using System.Collections.Generic; using System. ...
- JVM垃圾回收器总结
常见七种垃圾回收器以及使用的垃圾回收算法总结:
- Redis数据结构—跳跃表
目录 Redis数据结构-跳跃表 跳跃表产生的背景 跳跃表的结构 利用跳跃表查询有序链表 Redis跳跃表图示 Redis跳跃表数据结构 小结 Redis数据结构-跳跃表 大家好,我是白泽,最近学校有 ...
- Windows进程间通讯(IPC)----管道
管道的分类 管道其实际就是一段共享内存,只不过Windows规定需要使用I/O的形式类访问这块共享内存,管道可以分为匿名管道和命名管道. 匿名管道就是没有名字的管道,其支持单向传输数据,如果需要双向传 ...
- Linux的基础操作
1.概念 Linux是基于Unix的开源免费的操作系统,由于系统的稳定性和安全性几乎成为程序代码运行的最佳系统环境. 2.Linux的分类 1.按市场需求分为: 图形化界面版.服务器版 2.按原生程度 ...
- React中diff算法的理解
React中diff算法的理解 diff算法用来计算出Virtual DOM中改变的部分,然后针对该部分进行DOM操作,而不用重新渲染整个页面,渲染整个DOM结构的过程中开销是很大的,需要浏览器对DO ...
- 使用PuTTY连接Azure VM
使用PuTTY连接Azure VMhtml { -webkit-print-color-adjust: exact } * { box-sizing: border-box; -webkit-prin ...
- Python基础 小白[7天]入门笔记
笔记来源 Day-1 基础知识(注释.输入.输出.循环.数据类型.随机数) #-*- codeing = utf-8 -*- #@Time : 2020/7/11 11:38 #@Author : H ...
- 小白菜Windows10系统安装Linux(ubuntu)虚拟机超详细教程(全)
注:本文"( )"中的内容可忽略 1.下载VMware(威睿 计算机虚拟化软件) 官方下载地址 默认为最新版15.1.0,我们选择立即下载 (找一个比较大的盘不要是 ...