hdu2295-Radar
有n个城市,\(m\)个雷达,\(k\)个操作员,每个操作员只能操作一个雷达。每个雷达的覆盖范围是一个以雷达坐标为中心的圆,所有雷达的覆盖半径是相同的。
现在给出这\(n\)个城市,\(m\)个雷达的坐标,问雷达覆盖半径最小是多少,让所有城市都可以被雷达覆盖到。
\(T\le 1000,n,m,k\le 50,x,y\le 1000\)。
分析
二分答案,转化成判定性问题。这是一个最小支配集问题,已经被证明是NP难的,没有多项式的解法,所以使用搜索。又注意到这是一个覆盖的问题,可以使用Dancing Links数据结构来优化搜索。
这与DLX的一般问题,精确覆盖问题是不同的,因为一个城市可以被多个雷达覆盖,所以这是一个重复覆盖问题。这同样可以用DLX解决,因为它只是一个加速删除和回溯的数据结构而已。
重复覆盖,就是说一个列可以被覆盖多次,但每一列都要被覆盖。这样的话,我们只要每次在删除和回溯的时候,都只删除当前选择的这一行的所有元素的那些列,而不继续删除那些节点所在的行。这个在实现上有一些技巧。
for (int i=p[first].d;i!=first;i=p[i].d) {
del(i);
for (int j=p[i].r;j!=i;j=p[j].r) del(j);
bool ret=dance(now+1);
if (ret) return ret;
for (int j=p[i].l;j!=i;j=p[j].l) back(j);
back(i);
}
我们删除一列不是从列标开始删除,而是从当前的节点循环删除一轮,并且不删除当前节点。这是为了方便继续往下遍历,而且不删当前节点是没有影响的,因为这列上除了当前节点的点都被删掉了,所以不会访问到。而从行访问也是不需要的,所以可以这样做。
然而这样会TLE,因为在重复覆盖问题中,节点个数减少得很慢,导致算法的效率降低。所以我们一般需要加一些剪枝(其实一般都要加的),例如这题中的估价剪枝。
如果当前的答案加上最少需要再选多少行才能覆盖(只能估少,不能估多),已经大于\(k\)了,那么就可以剪掉。这个估价的方法是,枚举当前存在的每一列,如果没有tic就便利这一列有关的所有行,把所有行有关的列都打上tic,这算作选了一次,因为选的次数至少是这么多。
代码
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const double eps=1e-8;
const int maxn=55;
const int maxm=maxn*maxn;
struct cord {
double x,y;
} city[maxn],radar[maxn];
double dist(cord &a,cord &b) {
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int n,m,k;
struct node {
int l,r,u,d,col,row;
};
struct DLX {
node p[maxm];
int tot,last[maxn],size[maxn];
bool tic[maxn];
void clear() {
memset(p,0,sizeof p);
memset(last,0,sizeof last),memset(size,0,sizeof size);
tot=n;
p[0]=(node){n,1,0,0,0,0};
for (int i=1;i<=n;++i) {
p[i]=(node){i-1,i+1,i,i,0,i};
last[i]=i;
}
p[n].r=0;
}
void build(int row,int a[],int len) {
if (!len) return;
p[++tot]=(node){tot,tot,last[a[1]],p[last[a[1]]].d,a[1],row};
p[p[tot].u].d=p[p[tot].d].u=last[a[1]]=tot;
++size[a[1]];
for (int i=2;i<=len;++i) {
int x=a[i];
p[++tot]=(node){tot-1,p[tot-1].r,last[x],p[last[x]].d,x,row};
p[p[tot].l].r=p[p[tot].r].l=p[p[tot].u].d=p[p[tot].d].u=last[x]=tot;
++size[x];
}
}
void del(int c) {
for (int i=p[c].d;i!=c;i=p[i].d) p[p[i].l].r=p[i].r,p[p[i].r].l=p[i].l,--size[p[i].col];
}
void back(int c) {
for (int i=p[c].u;i!=c;i=p[i].u) p[p[i].l].r=p[p[i].r].l=i,++size[p[i].col];
}
int mi() {
memset(tic,0,sizeof tic);
int ret=0;
for (int i=p[0].r;i;i=p[i].r) if (!tic[i]) {
++ret;
tic[i]=true;
for (int j=p[i].d;j!=i;j=p[j].d) for (int q=p[j].r;q!=j;q=p[q].r) tic[p[q].col]=true;
}
return ret;
}
bool dance(int now) {
if (!p[0].r) return now<=k;
if (now+mi()>k) return false;
int first=p[0].r;
for (int i=p[0].r;i;i=p[i].r) if (size[i]<size[first]) first=i;
for (int i=p[first].d;i!=first;i=p[i].d) {
del(i);
for (int j=p[i].r;j!=i;j=p[j].r) del(j);
bool ret=dance(now+1);
if (ret) return ret;
for (int j=p[i].l;j!=i;j=p[j].l) back(j);
back(i);
}
return false;
}
} dlx;
bool ok(double rad) {
dlx.clear();
for (int i=1;i<=m;++i) {
static int c[maxn];
int tot=0;
for (int j=1;j<=n;++j)
if (dist(radar[i],city[j])<=rad)
c[++tot]=j;
dlx.build(i,c,tot);
}
bool flag=dlx.dance(0);
return flag;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
#endif
int T;
scanf("%d",&T);
while (T--) {
scanf("%d%d%d",&n,&m,&k);
for (int i=1;i<=n;++i) scanf("%lf%lf",&city[i].x,&city[i].y);
for (int i=1;i<=m;++i) scanf("%lf%lf",&radar[i].x,&radar[i].y);
double l=0,r=2000,ans,mid;
while (fabs(l-r)>eps) {
mid=(l+r)/2;
if (ok(mid)) ans=mid,r=mid; else l=mid;
}
printf("%.6lf\n",ans);
}
return 0;
}
hdu2295-Radar的更多相关文章
- HDU2295 Radar —— Dancing Links 可重复覆盖
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2295 Radar Time Limit: 2000/1000 MS (Java/Others) ...
- HDU2295 Radar (DLX)
下面的代码99%参考了这个网站http://www.cnblogs.com/183zyz/archive/2011/08/07/2130193.html 人生的第一道DLX肯定是需要作一些参考的啦. ...
- Dancing Links 专题总结
算法详细:Dancing Links博客 1.精确覆盖: ZOJ3209 Treasure Map HUST1017 Exact cover POJ3074 Sudoku 2.可重复覆盖: HDU22 ...
- HDU 2295 Radar (重复覆盖)
Radar Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- GNU Radio Radar Toolbox
GNU Radio Radar Toolbox Install guide Change to any folder in your home directory and enter followin ...
- radar js
<!doctype html> <html> <head> <meta charset="utf-8"> <link href ...
- [POJ1328]Radar Installation
[POJ1328]Radar Installation 试题描述 Assume the coasting is an infinite straight line. Land is in one si ...
- Radar Installation
Radar Installation 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=86640#problem/C 题目: De ...
- Radar Installation(贪心)
Radar Installation Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 56826 Accepted: 12 ...
- 贪心 POJ 1328 Radar Installation
题目地址:http://poj.org/problem?id=1328 /* 贪心 (转载)题意:有一条海岸线,在海岸线上方是大海,海中有一些岛屿, 这些岛的位置已知,海岸线上有雷达,雷达的覆盖半径知 ...
随机推荐
- Prism for WPF 搭建一个简单的模块化开发框架(六)隐藏菜单、导航
原文:Prism for WPF 搭建一个简单的模块化开发框架(六)隐藏菜单.导航 这个实际上是在聊天之前做的,一起写了,也不分先后了 看一下效果图,上面是模块主导航,左侧是模块内菜单,现在加一下隐藏 ...
- Ruby数据类型
数字类型 书写整数时,可以根据需要在整数之间任意加入下划线而不会影响数字的值 a=123_45_78 puts a # => 12345678 to_i 截掉小数点之后的数字取整 内置Math模 ...
- 二、StreamAPI
一.Stream是什么? 是数据通道,用于操作数据源(集合.数组等)所生成的元素序列.集合讲的是数据,流讲的是计算. 注意: Stream不会存储元素. Stream不会改变源对象.相反,他们会返回一 ...
- Win10 远程服务器版
朋友的电脑刚装了1803版的Win10,然后他用KMS_VL_ALL6.9激活了一下,竟然变成了一个奇怪的版本:“远程服务器版”!第一次见这玩意,还真稀罕.帮他研究了一下,发现KMS_VL_ALL在激 ...
- PS 拉伸大长腿
1.打开一个图片工具栏--图像--画布大小 2.选择矩形选框工具--框住要拉升退的位置--然后在按Ctrl+T,进行拉伸即可
- 「日常训练&知识学习」莫队算法(二):树上莫队(Count on a tree II,SPOJ COT2)
题意与分析 题意是这样的,给定一颗节点有权值的树,然后给若干个询问,每次询问让你找出一条链上有多少个不同权值. 写这题之前要参看我的三个blog:Codeforces Round #326 Div. ...
- 汽车VIN码,车架号,移动端,服务器端OCR识别 技术公司
很多人在购买车辆的时候,只关注性能.外观.内饰等,其实真正的内行是首先看车辆的VIN码,也叫车架号码. VIN码(车架号码)是一辆车的唯一身份证明,一般在车辆的挡风玻璃处,有的在车辆防火墙上,或B柱铭 ...
- 破解IDEA注册码,设置 license server一直有效不过期
破解的详细过程: 1.从下面地址下载一个jar包,名称是 JetbrainsCrack-2.10-release-enc.jar 下载地址是http://idea.lanyus.com/,进去之后点 ...
- Python元组与列表的区别和联系?
1. 元组和列表比较相似,不过它们之间也有着不同: (1)列表:一个大仓库,你可以随时往里边添加和删除任何东西. (2)元组:封闭的列表,一旦定义,就不可改变(不能添加.删除或修改). 2. 什么情 ...
- Python基础 之 文件操作
文件操作 一.路径 文件绝对路径:d:\python.txt 文件相对路径:在IDEA左边的文件夹中 二.编码方式 utf-8 gbk... 三.操作方式 1.只读 r 和 rb 绝对路径的打开操作 ...