洛谷P1783 海滩防御 分析+题解代码
洛谷P1783 海滩防御 分析+题解代码
题目描述:
WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭。于是,WLP动用了他那丰满且充实的大脑(或许更偏向前者),想出了一个好主意,他把海滩分成垂直于海岸线的若干列,在其中的几列上放置几个信号塔,试图来监视整个海滩。然而,WLP是一个非常心急的人,他把信号塔建好后才发现还需给信号塔供能,它们才能投入使用(这不是废话么),它们都有一个工作半径,一个圆形区域里的所有敌人都逃不过它们的监视,不过,WLP发现,敌人们非常狡猾,除非他将道路完全封死,否则WLP的敌人可以走过一条任意弯曲的路(不一定走整点,但是不会出第0列和第N列构成的边界)来偷他的东西。
于是,WLP就思考了:到底需要给每个信号塔多大的工作半径,才能将从海滩到内地的路径完全封死呢?他再次动用了他那丰满且充实的大脑,想了一堂数学课,终于,还是没想出来。于是,他向LZZ神犇求助(额……C_SUNSHINE的身份是不是暴露了)。
终于,在WLP:“%^!@#!(^!#@$^&(此处省略无数卖萌场景)”的哀求下,LZZ神犇写了一个程序,在1s内就解决了问题。但是,邪恶的LZZ神犇决定要将这个难题共享给无数无辜的OIer,所以,现在轮到你了。
输入格式:
第一行两个整数N和M:表示海滩被WLP分成的列数0-N和信号塔个数。
第2-M+1行:每行两个数Xi,Yi表示1-M号信号塔所在的列数和离开海滩的距离。
输出格式:
一行一个实数,表示最小的工作半径,保留两位小数。
样例输入1:
5 5
1 5
3 5
5 5
4 30
2 15
样例输出1:
1.00
样例输入2:
100 2
30 50
90 100
样例输出2:
39.05
说明:
对于10%的数据:1≤M≤10,1≤Yi≤100;
对于30%的数据:1≤M≤50,1≤Yi≤1,000;
对于80%的数据:1≤M≤500,1≤Yi≤1,000;
对于100%的数据:1≤M≤800,1≤N≤1000,1≤Xi≤N,1≤Yi≤100,000.
【样例解释】
注意,封锁海滩是指,敌人的深入程度是有限制的,若敌人绕过了所有的信号塔,并且可以长驱直入,那么就说明道路没有完全封锁。
算法分析:
复杂度可能不算很佳
但思路绝对简单
这里我们可以借鉴一下最小生成树的思想
即将整个图的所有边存于一个数组中(此步骤可以在输入防御塔坐标时完成)
此时图中只有节点而无边
将所有边按长度从小到大排序
然后依次加入这些边
每加入一条边就dfs遍历整个图
若此时图中某个联通块可以遍历到左右边界
此时的边权即为所求答案
还有几点需要注意的是
- 由于所求的是最小半径,所以计算边权的时候要将两点间距离除以二作为边权
- 海滩的列数编号为0~n,而0与n不能通行,所以左右边界为1与n-1
接下来献上蒟蒻的代码
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn=1000010;
typedef double dd;
int n,m;
struct node
{
dd x;
dd y;
}pt[maxn];
struct edge
{
int u;
int v;
dd dis;
}E[1000010];
bool vis[maxn];
bool lft,rht;//判断是否联通左右边界
vector<int> map[maxn];
dd dist(node a,node b)
{
dd tx=fabs(a.x-b.x);
dd ty=fabs(a.y-b.y);
tx*=tx;
ty*=ty;
return sqrt(tx+ty);
}
void dfs(int u,dd dis)
{
vis[u]=true;
//若到达左/右边界则记录
if(pt[u].y+dis>=n-1)
rht=true;
if(pt[u].y-dis<=1)
lft=true;
for(int j=0;j<map[u].size();j++)
{
int v=map[u][j];
if(vis[v]==false)
dfs(v,dis);
}
}
bool cmp(edge a,edge b)
{
return a.dis<b.dis;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>pt[i].y>>pt[i].x;
for(int j=1;j<i;j++)//在这里建边
{
E[++cont].u=i;
E[cont].v=j;
E[cont].dis=dist(pt[i],pt[j])/2.0;
//记得边权=两点距离/2.0
}
}
sort(E+1,E+1+cont,cmp);
for(int i=1;i<=cont;i++)//从小到大加入每条边
{
map[E[i].u].push_back(E[i].v);
map[E[i].v].push_back(E[i].u);
for(int j=1;j<=m;j++)
{
if(vis[j]==false)
dfs(j,E[i].dis);
if(lft&&rht)//若联通则直接输出并退出程序
{
printf("%.2lf",E[i].dis);
return 0;
}
else
lft=rht=false;
//注意判断封锁要在同一联通快内,所以每次都要重置
}
memset(vis,false,sizeof(vis));
}
return 0;
}
其实我们在边的加入时还可以有优化
但是由于本蒟蒻比较懒
所以不想在优化了。。。。。。
洛谷P1783 海滩防御 分析+题解代码的更多相关文章
- 洛谷 P1783 海滩防御 解题报告
P1783 海滩防御 题目描述 WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭 ...
- 洛谷 P1783 海滩防御
题目描述 WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭.于是,WLP动用了他 ...
- 洛谷P1783海滩防御
题目 跟奶酪那道题差不多,用并查集来求解. 用二分,或可以用类似于克鲁斯卡尔算法的贪心来每次判断是否起点和终点已经并在一个集合里(类似奶酪) 如果已经覆盖就结束判断并得出答案:即当前选择的边的最大值. ...
- 【luogu P1783 海滩防御】 题解
题目链接:https://www.luogu.org/problemnew/show/P1783 先把题目改造一下:题目所求是要一条能从0列到n列的路径,使其路径上的最大边长一半最小. 为什么是一半呢 ...
- 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication【最小割】分析+题解代码
洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication[最小割]分析+题解代码 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流. ...
- 洛谷 P2194 HXY烧情侣【Tarjan缩点】 分析+题解代码
洛谷 P2194 HXY烧情侣[Tarjan缩点] 分析+题解代码 题目描述: 众所周知,HXY已经加入了FFF团.现在她要开始喜(sang)闻(xin)乐(bing)见(kuang)地烧情侣了.这里 ...
- 洛谷P2832 行路难 分析+题解代码【玄学最短路】
洛谷P2832 行路难 分析+题解代码[玄学最短路] 题目背景: 小X来到了山区,领略山林之乐.在他乐以忘忧之时,他突然发现,开学迫在眉睫 题目描述: 山区有n座山.山之间有m条羊肠小道,每条连接两座 ...
- 洛谷P1854 花店橱窗布置 分析+题解代码
洛谷P1854 花店橱窗布置 分析+题解代码 蒟蒻的第一道提高+/省选-,纪念一下. 题目描述: 某花店现有F束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定 ...
- P1783 海滩防御
P1783 海滩防御 题目描述 WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭 ...
随机推荐
- TP传输的两种模式
主动模式(active): 我们知道,FTP是由TCP封包的模式连接,TCP 这种封包由于需要经过 Server 端与 Client 端两边的『三次握手』之后,才能确定联机,也就是需要执行AC ...
- C#编写影院售票系统(A project with a higher amount of gold )
项目需求: 影院售票系统 1.基础设施 放映厅 座位集合 2.一个海报------------>放映计划 3.售票设置----------->观影 领域模型:程序中提炼出的实体 4.从电影 ...
- 您是不是奇怪为什么 <script> 标签中没有 type="text/javascript" 属性?
在 HTML5 中该属性不是必需的.JavaScript 是 HTML5 以及所有现代浏览器中的默认脚本语言!
- MySQL Index Merge Optimization
Index Merge用在通过一些range scans得到检索数据行和合并成一个整体.合并可以通过 unions,intersections,或者unions-intersection运用在底层的扫 ...
- [知了堂学习笔记]_Java代码实现MySQL数据库的备份与还原
通常在MySQL数据库的备份和恢复的时候,多是采用在cmd中执行mysql命令来实现. 例如: mysqldump -h127.0.0.1 -uroot -ppass test > d:/tes ...
- c oth
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- python_如何在列表、字典中筛选数据?
实际问题有哪些? 过滤掉列表[3,9,-1,10.-2......] 中负数 筛选出字典{'li_ming':90,'xiao_hong':60,'li_kang':95,'bei_men':98} ...
- JAVAEE——BOS物流项目01:学习计划、搭建环境、主页设计(jQuery EasyUI)
1 学习计划 1.项目概述 项目背景介绍 2.搭建项目开发环境 数据库环境 maven项目搭建 svn环境搭建 3.主页设计(jQuery EasyUI) layout页面布局 accordion折叠 ...
- Linux指令--grep
原文地址:http://www.cnblogs.com/peida/archive/2012/12/17/2821195.html.感谢作者的无私分享. Linux系统中grep命令是一种强大的文本搜 ...
- Spring ioc,aop的理解
什么是控制反转? 控制反转是一种将组件依赖关系的创建和管理置于程序外部的技术. 由容器控制程序之间的关系,而不是由代码直接控制 由于控制权由代码转向了容器,所以称为反转 依赖注入,作用是避免手工在各代 ...