Radar



Problem Description
N cities of the Java Kingdom need to be covered by radars for being in a state of war. Since the kingdom has M radar stations but only K operators, we can at most operate K radars. All radars have the same circular coverage with a
radius of R. Our goal is to minimize R while covering the entire city with no more than K radars.
 
Input
The input consists of several test cases. The first line of the input consists of an integer T, indicating the number of test cases. The first line of each test case consists of 3 integers: N, M, K, representing the number of cities,
the number of radar stations and the number of operators. Each of the following N lines consists of the coordinate of a city.

Each of the last M lines consists of the coordinate of a radar station.



All coordinates are separated by one space.

Technical Specification



1. 1 ≤ T ≤ 20

2. 1 ≤ N, M ≤ 50

3. 1 ≤ K ≤ M

4. 0 ≤ X, Y ≤ 1000
 
Output
For each test case, output the radius on a single line, rounded to six fractional digits.
 
Sample Input
1
3 3 2
3 4
3 1
5 4
1 1
2 2
3 3
 
Sample Output
2.236068
 
Source

解题思路:

题意为有m个雷达,每一个雷达的覆盖范围都为以r为半径的圆,给定他们的坐标,有n个城市。给定他们的坐标,求最小的r,使得每一个城市都被雷达覆盖。限制条件为最多仅仅有k个雷达工作。

二分答案r。推断所须要的雷达数是否小于给定的k,找到最小的r。

用Dlx反复覆盖来推断。首先建图:m行,n列的矩形,也就是横坐标代表雷达。纵坐标代表城市,假设雷达与城市之间的距离小于等于当前的r,则坐标处标记为1。否则为0,这样就转化为了01矩阵,也就是解决这个问题能不能在这个矩阵中找出一些行(行数小于等于k),使得这些行组成的新矩阵,每列都至少有一个1(反复覆盖。每列能够有多个1).

注意maxnode的范围 ,最大不能仅仅是 n*m, 列头结点还得加上 即  n*m+m

关于精确覆盖和反复覆盖,以下转载于:http://www.cnblogs.com/jh818012/p/3252154.html

精确覆盖:

首先选择当前要覆盖的列(含1最少的列)。将该列和可以覆盖到该列的行所有去掉,再枚举加入的方法。

枚举某一行r,如果它是解集中的一个,那么该行所能覆盖到的全部列都不必再搜,所以删除该行覆盖到的全部列,又因为去掉的列相当于有解,所以可以覆盖到这些列的行也不用再搜,删之。

反复覆盖:

首先选择当前要覆盖的列(同上),将该列删除,枚举覆盖到该列的全部行:对于某一行r,如果它是解集中的一个。那么该行所能覆盖到的列都不必再搜。所以删除该行覆盖到的全部列。

注意此时不用删去覆盖到这些列的行,由于一列中同意有多个1。

这里有一个A*的优化:估价函数h意义为从当前状态最好情况下须要加入几条边才干覆盖。

代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int maxn=52;
const int maxm=52;
const int maxnode=3020;
int n,m,k; struct DLX
{
int n,m,size;
int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
int H[maxn],S[maxn];
int ansd,ans[maxn]; void init(int _n,int _m)
{
n=_n;
m=_m;
for(int i=0;i<=m;i++)
{
S[i]=0;
U[i]=D[i]=i;
L[i]=i-1;
R[i]=i+1;
}
R[m]=0,L[0]=m;
size=m;
for(int i=1;i<=n;i++)
H[i]=-1;
} void link(int r,int c)
{
++S[Col[++size]=c];
Row[size]=r;
D[size]=D[c];
U[D[c]]=size;
U[size]=c;
D[c]=size;
if(H[r]<0)
H[r]=L[size]=R[size]=size;
else
{
R[size]=R[H[r]];
L[R[H[r]]]=size;
L[size]=H[r];
R[H[r]]=size;
}
} void remove(int c)
{
for(int i=D[c];i!=c;i=D[i])
L[R[i]]=L[i],R[L[i]]=R[i];
} void resume(int c)
{
for(int i=U[c];i!=c;i=U[i])
L[R[i]]=R[L[i]]=i;
} bool v[maxnode]; int f()//精确覆盖区估算剪枝
{
int ret=0;
for(int c=R[0];c!=0;c=R[c])
v[c]=true;
for(int c=R[0];c!=0;c=R[c])
if(v[c])
{
ret++;
v[c]=false;
for(int i=D[c];i!=c;i=D[i])
for(int j=R[i];j!=i;j=R[j])
v[Col[j]]=false;
}
return ret;
} bool dance(int d)
{
if(d+f()>k)
return false;
if(d>k)
return false;
if(R[0]==0)
return true;
int c=R[0];
for(int i=R[0];i!=0;i=R[i])
if(S[i]<S[c])
c=i;
for(int i=D[c];i!=c;i=D[i])
{
remove(i);
for(int j=R[i];j!=i;j=R[j])
remove(j);
if(dance(d+1)) return true;
for(int j=L[i];j!=i;j=L[j])
resume(j);
resume(i);
}
return false;
}
}; DLX g;
const double eps=1e-8; struct point
{
double x,y;
}city[maxm],radar[maxn]; double dis(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
} int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&m,&n,&k);
for(int i=1;i<=m;i++)
scanf("%lf%lf",&city[i].x,&city[i].y);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&radar[i].x,&radar[i].y);
double l=0,r=1e5;
while(r-l>=eps)
{
double mid=(l+r)/2.0;
g.init(n,m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(dis(radar[i],city[j])<mid-eps)
g.link(i,j);
if(g.dance(0))
r=mid-eps;
else
l=mid+eps;
}
printf("%.6lf\n",l);
}
return 0;
}

版权声明:本文博主原创文章,博客,未经同意不得转载。

[ACM] HDU 2295 Radar (二分法+DLX 重复覆盖)的更多相关文章

  1. HDU 2295 Radar dancing links 重复覆盖

    就是dancing links 求最小支配集,重复覆盖 精确覆盖时:每次缓存数据的时候,既删除行又删除列(这里的删除列,只是删除表头) 重复覆盖的时候:只删除列,因为可以重复覆盖 然后重复覆盖有一个估 ...

  2. HDU 5046 Airport【DLX重复覆盖】

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5046 题意: 给定n个城市的坐标,要在城市中建k个飞机场,使城市距离最近的飞机场的最长距离最小,求这 ...

  3. HDU 3335 Divisibility dancing links 重复覆盖

    分析: dlx重复覆盖的巧用,重复覆盖的原理恰好符合本题的筛选方式,即选择一个数后,该数的倍数或约数可以保证在之后的搜索中不会被选择 于是修改一下启发函数,求解最大的重复覆盖即可.   其实不一定不被 ...

  4. HDU 2295.Radar (DLX重复覆盖)

    2分答案+DLX判断可行 不使用的估计函数的可重复覆盖的搜索树将十分庞大 #include <iostream> #include <cstring> #include < ...

  5. HDU 2295 Radar 重复覆盖 DLX

    题意: N个城市,M个雷达站,K个操作员,问雷达的半径至少为多大,才能覆盖所有城市.M个雷达中最多只能有K个同时工作. 思路: 二分雷达的半径,看每个雷达可以覆盖哪些城市,然后做重复覆盖,判断这个半径 ...

  6. HDU 2295 Radar (重复覆盖)

    Radar Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  7. HDU 2295 Radar (二分 + Dancing Links 重复覆盖模型 )

    以下转自 这里 : 最小支配集问题:二分枚举最小距离,判断可行性.可行性即重复覆盖模型,DLX解之. A*的启发函数: 对当前矩阵来说,选择一个未被控制的列,很明显该列最少需要1个行来控制,所以ans ...

  8. hdu 2295 dlx重复覆盖+二分答案

    题目大意: 有一堆雷达工作站,安放至多k个人在这些工作站中,找到一个最小的雷达监控半径可以使k个工作人所在的雷达工作站覆盖所有城市 二分半径的答案,每次利用dlx的重复覆盖来判断这个答案是否正确 #i ...

  9. (中等) HDU 3335 , DLX+重复覆盖。

    Description As we know,the fzu AekdyCoin is famous of math,especially in the field of number theory. ...

随机推荐

  1. Objective-C之成魔之路【9-类构造方法和成员变量作用域、以及变量】

    郝萌主倾心贡献,尊重作者的劳动成果.请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 构造方法 ...

  2. 项目架构mvc+webapi

    mvc+webapi 项目架构 首先项目是mvc5+webapi2.0+orm-dapper+ef codefirst. 1.项目框架层次结构: 这个mvc项目根据不同的业务和功能进行不同的区域划分, ...

  3. ngrok 本机代码部署外网访问神器(转)

    背景:听哥们说了个工具ngrok,可以让本机配置的web服务在外网访问,抱着将信将疑的态度试了试,发现还真的可以.下面记录下我自己的安装步骤,另外谈下自己还有些疑问的地方. 参考资料网站:http:/ ...

  4. 【2014 Multi-University Training Contest 3 1002】/【HDU 4888】 Redraw Beautiful Drawings

    不easy啊.最终能够补第二个题了.! 顺便说一句:模版写残了就不要怪出题人啊 ~ (这残废模版研究了好长时间才找出错) 题目大意: 有一个n*m的矩阵.每个格子里都将有一个数.给你每一行数字之和和每 ...

  5. swift-辞典NSDictionary定义,变化的关键,删/加入关键

    // Playground - noun: a place where people can play import UIKit //--------------------------------- ...

  6. abstract修改方法

    abstract这种方法修饰,主要用在抽象类和抽象方法. 抽象的类是不可实例化的比如 public abstract class Test{ } 他能够含有抽象的方法 public abstract ...

  7. Java二叉排序树(转)

    一.二叉排序树定义 1.二叉排序树的定义 二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree).其定义为:二叉排序树或者是空树,或者是满足如下性 ...

  8. 【原创】纯OO:从设计到编码写一个FlappyBird (三)

    第二部分请点这里 下面首先来实现Bing接口! 实现Bing接口的类取名SimpleBing. 容易发现,SimpleBing类总的来说要向下,但点击一下又得向上,向上到了一定界限又得向下,但我们又只 ...

  9. C++学习笔记9-运算符重载

    1. 重载运营商必须有一个类类型的操作数 对于内置类型运营商.它的意义不能改变. 例如,内置整数加法运算不能被重新定义: // error: cannotredefine built-in opera ...

  10. js多物体任意值运动

    假如有两个div,一个div要变宽,一个div要变高,你怎么写呢? 哎呀,写2个方法啊,一个控制div1变宽,一个控制div2变高啊 那么你的代码,是不是下面这样的呢! 示例:Div变宽和变高 现象: ...