题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2295

Radar

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4106    Accepted Submission(s): 1576

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

题解:

超时方法:

1.对于DLX的矩阵:行代表着雷达与城市的距离, 列代表着城市。矩阵大小250*50。

2.Dancing跳起来,当R[0]==0时, 取当前所选行中,距离的最大值dis(这样才能覆盖掉所有城市),然后再更新答案ans,ans = min(ans, dis)。

3.结果矩阵有点大, 超时了。

4.错误思想分析:把雷达与城市的距离作为行,实际上是太明智的。因为题目说明了每个雷达的接收半径是相同的,而以上方法选出来的每个雷达的接收半径是相异的,然后又再取最大值,那为何不每次都取最大值(相同值)呢? 如果取相同值,那么行就是雷达,列就是城市,矩阵的大小就减少了。但是又怎么确定雷达的接收半径呢?如下:

正确方法:

1.雷达作为行, 城市作为列。

2.二分雷达的接收范围,每次二分都:根据接收半径更新矩阵中所含的元素,然后再进行一次Dance(),如果能覆盖掉所有城市,则缩小半径,否则扩大半径。

超时方法:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int INF = 2e9;
const int MAXN = +;
const int MAXM = +;
const int maxnode = 1e5+; double city[MAXN][], radar[MAXN][];
double r[MAXN*MAXM];
int k; struct DLX
{
int n, m, size;
int U[maxnode], D[maxnode], L[maxnode], R[maxnode], Row[maxnode], Col[maxnode];
int H[MAXN*MAXM], S[MAXN*MAXM];
double ansd, ans[MAXN*MAXM]; void init(int _n, int _m)
{
n = _n;
m = _m;
for(int i = ; i<=m; i++)
{
S[i] = ;
U[i] = D[i] = i;
L[i] = i-;
R[i] = i+;
}
R[m] = ; L[] = m;
size = m;
for(int i = ; i<=n; i++) H[i] = -;
} void Link(int r, int c)
{
size++;
Row[size] = r;
Col[size] = c;
S[Col[size]]++;
D[size] = D[c];
U[D[c]] = size;
U[size] = c;
D[c] = size;
if(H[r]==-) 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];
} bool v[MAXM];
int f()
{
int ret = ;
for(int c = R[]; c!=; c = R[c])
v[c] = true;
for(int c = R[]; c!=; 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;
} void resume(int c)
{
for(int i = U[c]; i!=c; i = U[i])
L[R[i]] = R[L[i]] = i;
} void Dance(int d)
{
if(d+f()>k) return;
if(R[]==)
{
double tmp = -1.0;
for(int i = ; i<d; i++)
tmp = max(tmp, ans[i]);
ansd = min(tmp, ansd);
return;
} int c = R[];
for(int i = R[]; i!=; i = R[i])
if(S[i]<S[c])
c = i;
for(int i = D[c]; i!=c; i = D[i])
{
ans[d] = r[Row[i]];
remove(i);
for(int j = R[i]; j!=i; j = R[j]) remove(j);
Dance(d+);
for(int j = L[i]; j!=i; j = L[j]) resume(j);
resume(i);
}
}
}; double dis(double x1, double y1, double x2, double y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
} DLX dlx;
int main()
{
int T;
int n, m;
scanf("%d", &T);
while(T--)
{
scanf("%d%d%d", &n, &m, &k);
dlx.init(n*m, n);
for(int i = ; i<=n; i++)
scanf("%lf%lf",&city[i][], &city[i][]);
for(int i = ; i<=m; i++)
scanf("%lf%lf",&radar[i][], &radar[i][]); for(int i = ; i<=m; i++)
for(int j = ; j<=n; j++)
{
double tmp = dis(radar[i][], radar[i][], city[j][], city[j][]);
r[(i-)*n+j] = tmp;
for(int t = ; t<=n; t++)
if(dis(radar[i][], radar[i][], city[t][], city[t][])<=tmp)
dlx.Link((i-)*n+j, t);
}
dlx.ansd = 1.0*INF;
dlx.Dance();
printf("%.6f\n", dlx.ansd);
}
return ;
}

正确方法:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int INF = 2e9;
const double EPS = 1e-;
const int MAXN = +;
const int MAXM = +;
const int maxnode = 1e5+; double city[MAXN][], radar[MAXN][];
double r[MAXN*MAXM];
int k; struct DLX
{
int n, m, size;
int U[maxnode], D[maxnode], L[maxnode], R[maxnode], Row[maxnode], Col[maxnode];
int H[MAXN*MAXM], S[MAXN*MAXM];
double ansd, ans[MAXN*MAXM]; void init(int _n, int _m)
{
n = _n;
m = _m;
for(int i = ; i<=m; i++)
{
S[i] = ;
U[i] = D[i] = i;
L[i] = i-;
R[i] = i+;
}
R[m] = ; L[] = m;
size = m;
for(int i = ; i<=n; i++) H[i] = -;
} void Link(int r, int c)
{
size++;
Row[size] = r;
Col[size] = c;
S[Col[size]]++;
D[size] = D[c];
U[D[c]] = size;
U[size] = c;
D[c] = size;
if(H[r]==-) 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[MAXM];
int f()
{
int ret = ;
for(int c = R[]; c!=; c = R[c])
v[c] = true;
for(int c = R[]; c!=; 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(R[]==) return true; int c = R[];
for(int i = R[]; i!=; 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+))return true;
for(int j = L[i]; j!=i; j = L[j]) resume(j);
resume(i);
}
return false;
}
}; double dis(double x1, double y1, double x2, double y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
} DLX dlx;
int main()
{
int T;
int n, m;
scanf("%d", &T);
while(T--)
{
scanf("%d%d%d", &n, &m, &k);
for(int i = ; i<=n; i++)
scanf("%lf%lf",&city[i][], &city[i][]);
for(int i = ; i<=m; i++)
scanf("%lf%lf",&radar[i][], &radar[i][]); double l = 0.0, r = 2000.0;
while(l+EPS<=r)
{
double mid = (l+r)/;
dlx.init(m, n);
for(int i = ; i<=m; i++)
for(int j = ; j<=n; j++)
if(dis(radar[i][], radar[i][], city[j][], city[j][])<=mid)
dlx.Link(i, j);
if(dlx.Dance())
r = mid - EPS;
else
l = mid + EPS;
}
printf("%.6lf\n",l);
}
return ;
}

HDU2295 Radar —— Dancing Links 可重复覆盖的更多相关文章

  1. FZU1686 神龙的难题 —— Dancing Links 可重复覆盖

    题目链接:https://vjudge.net/problem/FZU-1686 Problem 1686 神龙的难题 Accept: 812    Submit: 2394 Time Limit: ...

  2. HDU 2295 Radar dancing links 重复覆盖

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

  3. 【POJ3740】Easy Finding DLX(Dancing Links)精确覆盖问题

    题意:多组数据,每组数据给你几行数,要求选出当中几行.使得每一列都有且仅有一个1.询问是可不可行,或者说能不能找出来. 题解:1.暴搜.2.DLX(Dancing links). 本文写的是DLX. ...

  4. hihoCoder #1321 : 搜索五•数独 (Dancing Links ,精确覆盖)

    hiho一下第102周的题目. 原题地址:http://hihocoder.com/problemset/problem/1321 题意:输入一个9*9数独矩阵,0表示没填的空位,输出这个数独的答案. ...

  5. hust 1017 dancing links 精确覆盖模板题

    最基础的dancing links的精确覆盖题目 #include <iostream> #include <cstring> #include <cstdio> ...

  6. ZOJ 3209 Treasure Map (Dancing Links 精确覆盖 )

    题意 :  给你一个大小为 n * m 的矩形 , 坐标是( 0 , 0 ) ~ ( n , m )  .然后给你 p 个小矩形 . 坐标是( x1 , y1 ) ~ ( x2 , y2 ) , 你选 ...

  7. 浅入 dancing links x(舞蹈链算法)

    abastract:利用dancing links 解决精确覆盖问题,例如数独,n皇后问题:以及重复覆盖问题. 要学习dacning links 算法,首先要先了解该算法适用的问题,精确覆盖问题和重复 ...

  8. poj 3074 Sudoku(Dancing Links)

    Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8152   Accepted: 2862 Descriptio ...

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

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

随机推荐

  1. 洛谷P3393 逃离僵尸岛

    题目描述 小a住的国家被僵尸侵略了!小a打算逃离到该国唯一的国际空港逃出这个国家. 该国有N个城市,城市之间有道路相连.一共有M条双向道路.保证没有自环和重边. K个城市已经被僵尸控制了,如果贸然闯入 ...

  2. 转 Linux文件管理

    Linux文件管理 http://www.cnblogs.com/vamei/archive/2012/09/09/2676792.html 作者:Vamei 出处:http://www.cnblog ...

  3. leetcode 15. 3Sum 二维vector

    传送门 15. 3Sum My Submissions Question Total Accepted: 108534 Total Submissions: 584814 Difficulty: Me ...

  4. IOC基本理解

    什么是IOC? IOC全称为控制反转(Inversion Of Control),别名依赖注入(Dependency Injection). 控制反转即指我们获取依赖的方式发生了反转. 假设存在如下情 ...

  5. 洛谷——P1290 欧几里德的游戏

    P1290 欧几里德的游戏 题目描述 欧几里德的两个后代Stan和Ollie正在玩一种数字游戏,这个游戏是他们的祖先欧几里德发明的.给定两个正整数M和N,从Stan开始,从其中较大的一个数,减去较小的 ...

  6. CODEVS 1245 最小的N个和 堆+排序

    原题链接 http://codevs.cn/problem/1245/ 题目描述 Description 有两个长度为 N 的序列 A 和 B,在 A 和 B 中各任取一个数可以得到 N^2 个和,求 ...

  7. Java中循环与选择语句

    public class Ifelse{ public static void main(String [] args){ int score=98; if(score>=90&& ...

  8. 【面试 JVM】【第六篇】JVM调优

    六部分内容: 一.内存模型 1.程序计数器,方法区,堆,栈,本地方法栈的作用,保存那些数据 可以画个大图出来,很清晰 jvm内存模型主要指运行时的数据区,包括5个部分. 栈也叫方法栈,是线程私有的,线 ...

  9. XP操作系统设置:[82]关机快捷键

    磨镰刀不少割麦,掌握了快速关机的多种方法,在尴尬的时候说不定还真能派上用场呢.   工具/原料   手提电脑.台式电脑.Windows 操作系统. 方法一:   1 Windows XP 操作系统中有 ...

  10. mongoVUE 破解方法

    mongoVUE1.5.3的破解方法其实很简单 注册表中查找B1159E65-821C3-21C5-CE21-34A484D54444中的子项4FF78130 ,删除其下的三个子项即可. 开始-运行- ...