HDU2295 Radar —— Dancing Links 可重复覆盖
题目链接: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
minimize R while covering the entire city with no more than K radars.
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
3 3 2
3 4
3 1
5 4
1 1
2 2
3 3
题解:
超时方法:
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 可重复覆盖的更多相关文章
- FZU1686 神龙的难题 —— Dancing Links 可重复覆盖
题目链接:https://vjudge.net/problem/FZU-1686 Problem 1686 神龙的难题 Accept: 812 Submit: 2394 Time Limit: ...
- HDU 2295 Radar dancing links 重复覆盖
就是dancing links 求最小支配集,重复覆盖 精确覆盖时:每次缓存数据的时候,既删除行又删除列(这里的删除列,只是删除表头) 重复覆盖的时候:只删除列,因为可以重复覆盖 然后重复覆盖有一个估 ...
- 【POJ3740】Easy Finding DLX(Dancing Links)精确覆盖问题
题意:多组数据,每组数据给你几行数,要求选出当中几行.使得每一列都有且仅有一个1.询问是可不可行,或者说能不能找出来. 题解:1.暴搜.2.DLX(Dancing links). 本文写的是DLX. ...
- hihoCoder #1321 : 搜索五•数独 (Dancing Links ,精确覆盖)
hiho一下第102周的题目. 原题地址:http://hihocoder.com/problemset/problem/1321 题意:输入一个9*9数独矩阵,0表示没填的空位,输出这个数独的答案. ...
- hust 1017 dancing links 精确覆盖模板题
最基础的dancing links的精确覆盖题目 #include <iostream> #include <cstring> #include <cstdio> ...
- ZOJ 3209 Treasure Map (Dancing Links 精确覆盖 )
题意 : 给你一个大小为 n * m 的矩形 , 坐标是( 0 , 0 ) ~ ( n , m ) .然后给你 p 个小矩形 . 坐标是( x1 , y1 ) ~ ( x2 , y2 ) , 你选 ...
- 浅入 dancing links x(舞蹈链算法)
abastract:利用dancing links 解决精确覆盖问题,例如数独,n皇后问题:以及重复覆盖问题. 要学习dacning links 算法,首先要先了解该算法适用的问题,精确覆盖问题和重复 ...
- poj 3074 Sudoku(Dancing Links)
Sudoku Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8152 Accepted: 2862 Descriptio ...
- HDU 2295 Radar (二分 + Dancing Links 重复覆盖模型 )
以下转自 这里 : 最小支配集问题:二分枚举最小距离,判断可行性.可行性即重复覆盖模型,DLX解之. A*的启发函数: 对当前矩阵来说,选择一个未被控制的列,很明显该列最少需要1个行来控制,所以ans ...
随机推荐
- poj 3608 凸包间的最小距离
Bridge Across Islands Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7632 Accepted: ...
- uva 11021
题意:有k只麻球,每只活一天就会死亡,临死之前可能会生出一些新的麻球.具体来说,生i个麻球的概率为pi.给定m,求m天后所有麻球死亡的概率.注意,不足m天时就已经全部死亡的情况也算在内. 分析:由于每 ...
- AnyChart创建实时仪表
AnyChart创建实时仪表 简述: AnyChart是一款基于Flash和HTML5的图表.仪表控件,所包含的图表类型众多和跨平台以及跨浏览器是该产品的主要特点和优点,另外该产品基于XML文件作为数 ...
- msp430项目编程33
msp430中项目---简易示波器系统 1.电路工作原理 2.代码(显示部分) 3.代码(功能实现) 4.项目总结
- Mac 10.9 安装及使用 phoneGap
公司网速是个坑啊 绝对掉进去就起不来的那种..... 按官网的说法: 1. 下载并安装Node.js 2. sudo npm install -g phonegap 官网的安装步骤到此为止....坑 ...
- I.Tower Defense
给你p个重塔,q个轻塔,把这些塔放在n*m的图中,这些塔会相互攻击同行同列的,轻塔不能受到攻击,重塔能承受一个塔的攻击, 问放的方法数. 先假定n < m. 可以先枚举放轻塔的个数为s,显然,方 ...
- synchronized初识
作用域: 1.对象实例内--->People jack = new Jack(); ①此作用域内的synchronized锁 ,可以防止多个线程同时访问这个对象的synchronized方法 ② ...
- Java并发编程实战 读书笔记(二)
关于发布和逸出 并发编程实践中,this引用逃逸("this"escape)是指对象还没有构造完成,它的this引用就被发布出去了.这是危及到线程安全的,因为其他线程有可能通过这个 ...
- 【面试 JDK】【第一篇】Object类面试详解
1.Object类有哪些方法 1>clone()方法 保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异 ...
- SolidEdge 工程图中如何快速将同一类元素放到同一个图层
在图层选项卡中新建一个尺寸线图层 点击聪慧选项(把它点凹下去),然后点击任意尺寸线,弹出聪慧选取选项,点击确定,则自动选择了所有尺寸线 点击移动图元,把刚才选中的所有尺寸线都移动到这个图层即可 ...