HDU 2295 Radar 重复覆盖 DLX
2014-11-16 21:17
405 查看
题意:
N个城市,M个雷达站,K个操作员,问雷达的半径至少为多大,才能覆盖所有城市。M个雷达中最多只能有K个同时工作。
思路:
二分雷达的半径,看每个雷达可以覆盖哪些城市,然后做重复覆盖,判断这个半径是否可行。
我是直接二分的半径,跑了300+ms,看了Virtual Judge上面跑得快的代码,才发现为了不浪费半径的长度,最小的半径一定等于某一个雷达站到某一个城市之间的距离。这样一来枚举量就小了很多,只需要15ms……
代码:
300+ms的 -_-
View Code
N个城市,M个雷达站,K个操作员,问雷达的半径至少为多大,才能覆盖所有城市。M个雷达中最多只能有K个同时工作。
思路:
二分雷达的半径,看每个雷达可以覆盖哪些城市,然后做重复覆盖,判断这个半径是否可行。
我是直接二分的半径,跑了300+ms,看了Virtual Judge上面跑得快的代码,才发现为了不浪费半径的长度,最小的半径一定等于某一个雷达站到某一个城市之间的距离。这样一来枚举量就小了很多,只需要15ms……
代码:
300+ms的 -_-
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> #include <string> #include <queue> #include <stack> #include <vector> #include <map> #include <set> #include <functional> #include <cctype> #include <time.h> using namespace std; const double eps = 1e-8; const int INF = 1<<30; const int MAXN = 55; const int MAXR = 55; const int MAXNODE = MAXN*MAXR; struct DLX { // 行编号从1开始,列编号为1~n,结点0是表头结点;结点1~n是各列顶部的虚拟结点 int n, sz; // 列数,结点总数 int S[MAXN]; //各列结点数 int row[MAXNODE], col[MAXNODE]; //各结点行列编号 int L[MAXNODE], R[MAXNODE], U[MAXNODE], D[MAXNODE]; //十字链表 int ansd, ans[MAXR]; // 解 void init(int n) { //n是列数 this->n = n; //虚拟结点 for (int i = 0; i <= n; i++) { U[i] = i; D[i] = i; L[i] = i-1; R[i] = i+1; } R = 0; L[0] = n; sz = n+1; memset(S, 0, sizeof(S)); } void addRow(int r, vector<int> columns) { //这一行的第一个结点 //行没有设头结点,每一行连成一个环形 int first = sz; for (int i = 0; i < columns.size(); i++) { int c = columns[i]; L[sz] = sz-1; R[sz] = sz+1; D[sz] = c; U[sz] = U[c]; D[U[c]] = sz; U[c] = sz; row[sz] = r; col[sz] = c; S[c]++; sz++; } R[sz-1] = first; L[first] = sz-1; } //顺着链表A,遍历s外的其他元素 #define FOR(i, A, s) for (int i = A[s]; i != s; i = A[i]) void remove(int c) { //删除c列 FOR(i, D, c) { L[R[i]] = L[i]; R[L[i]] = R[i]; } } void restore(int c) { //回连c列 FOR(i, U, c) { L[R[i]] = R[L[i]] = i; } } bool vis[MAXN]; int f() { int ret = 0; FOR(c, R, 0) vis[c] = true; FOR(c, R, 0) if (vis[c]) { ret++; vis[c] = false; FOR(i, D, c) FOR(j, R, i) vis[col[j]] = false; } return ret; } void dfs(int d) { //d为递归深度 if (d+f()>=ansd) return ; if (R[0] == 0) { //找到解 ansd = min(ansd, d); //记录解的长度 return ; } //找S最小的C列 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]) { //用结点i所在的行覆盖第c列 remove(i); for (int j = R[i]; j != i; j = R[j]) remove(j); //删除节结点i所在行覆盖第c列 ans[d] = row[i]; dfs(d+1); for (int j = L[i]; j != i; j = L[j]) restore(j); // 恢复 restore(i); } } int solve() { ansd = INF; dfs(0); return ansd; } }; DLX solver; vector<int> columns; int n, m, k; double a[MAXN][2]; double b[MAXN][2]; double G[MAXN][MAXN]; int check(double x) { solver.init(n); for (int i = 0; i < m; i++) { columns.clear(); for (int j = 0; j < n; j++) if (G[i][j]<=x) columns.push_back(j+1); if (!columns.empty()) solver.addRow(i+1, columns); } return solver.solve(); } int main() { #ifdef Phantom01 freopen("HDU2295.txt", "r", stdin); #endif //Phantom01 int T; scanf("%d", &T); while (T--) { scanf("%d%d%d", &n, &m, &k); for (int i = 0; i < n; i++) scanf("%lf%lf", &a[i][0], &a[i][1]); for (int i = 0; i < m; i++) scanf("%lf%lf", &b[i][0], &b[i][1]); double l = 0, r = 0, mm; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { G[i][j] = sqrt((b[i][0]-a[j][0])*(b[i][0]-a[j][0]) + (b[i][1]-a[j][1])*(b[i][1]-a[j][1])); r = max(r, G[i][j]); } } while (abs(r-l)>eps) { mm = (l+r)/2; if (check(mm)>k) l = mm; else r = mm; } printf("%.6f\n", r+eps); } return 0; }
View Code
相关文章推荐
- HDU 2295 Radar (二分+DLX,重复覆盖)
- HDU 2295 Radar (DLX求重复覆盖, A*搜索)
- HDU 2295 Radar(二分+DLX重复覆盖)
- HDU 2295 Radar(DLX可重复覆盖)
- 搜索(DLX重复覆盖模板):HDU 2295 Radar
- HDU 2295 Radar(重复覆盖,DLX)
- HDU 2295 Radar (DLX可重复覆盖+二分)
- hdu 2295 Radar(重复覆盖,二分+DLX)
- [ACM] HDU 2295 Radar (二分+DLX 重复覆盖)
- HDU 2295 Radar (二分 + Dancing Links 重复覆盖模型 )
- 【HDU】2295 Radar 二分+重复覆盖
- hdu 2295 Radar 重复覆盖 DLX+二分答案 给出一些城市及一些雷达的坐标,要求从这些雷达中选取最多k个能够覆盖所有的城市,问雷达的最小覆盖半径为多少
- hdu 2295 Radar(重复覆盖问题)
- hdu 2295 Radar(Dancing Links重复覆盖)
- HDU_2295_Radar(DancingLinksX重复覆盖+二分)
- hdu 2295 dlx重复覆盖+二分答案
- [ACM] HDU 2295 Radar (二分法+DLX 重复覆盖)
- HDU 2295 Radar(二分+重复覆盖)
- HDU 2295 Radar(重复覆盖|Dancing Links)
- hdu 2295 Radar (二分答案+重复覆盖)