题目链接: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. Laravel 5 Form 和 HTML 的使用

    最近在用 laravel 5 做例子,在做到表单的时候,习惯性的使用 Form::open() 结果发现提示错误,没有这个类, 好吧,找了找,发现 在laravel 5 中,把 from 和 html ...

  2. Codeforces Round #278 (Div. 2) B. Candy Boxes [brute force+constructive algorithms]

    哎,最近弱爆了,,,不过这题还是不错滴~~ 要考虑完整各种情况 8795058                 2014-11-22 06:52:58     njczy2010     B - Ca ...

  3. laravel 的模型

    建立model文件,再项目的app目录下建立Member.php namespace App; use Illuminate\Database\Eloquent\Model; class Member ...

  4. SGU 107 数学题

    题意:求平方后末尾9个数是987654321的数个数. 之前做此题,竟然愚蠢到用计算器 在哪里算,还加笔算,SB啊!不知道先打印一下吗! #include<iostream> #inclu ...

  5. 洛谷P1865 A % B Problem

    1.洛谷P1865 A % B Problem 题目背景 题目名称是吸引你点进来的 实际上该题还是很水的 题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m 接下来n行 ...

  6. ubuntu16.04安装mysql5.7.15

    1.在官网下载mysql安装包 直接选择第一个下载好了就行 2.进入你的下载文件夹下面 键入命令: tar -xvf mysql-server_5.7.13-1ubuntu16.04_i386.deb ...

  7. Maven学习在Elipse中发布一个Maven项目到Tomcat

    原文:http://www.cnblogs.com/quanyongan/archive/2013/04/26/3044618.html 对于maven初学者的我,经常遇到一个问题就是,maven项目 ...

  8. init.rc文件中面启动c++程序,通过jni调用java实现

    </pre><p>注:假设是自己的myself.jar包,还要修改例如以下:</p><p>target/product/core_base.mk PRO ...

  9. U盘容纳不了大于4G的文件比如ISO文件咋办?

    格式化U盘成NTFS格式就行了,不这么做8,16,32G Upan都容纳不下来.

  10. poj1159--Palindrome(dp:最长公共子序列变形 + 滚动数组)

    Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 53414   Accepted: 18449 Desc ...