HDU 5046 Airport【DLX重复覆盖】
来源:互联网 发布:url编码 js 编辑:程序博客网 时间:2024/05/16 17:03
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5046
题意:
给定
分析:
最小化最大值,显然二分最大距离。然后我们将距离在范围内的两个城市建边,看能否选出
将点之间的关系转化成01矩阵的覆盖问题,重复覆盖,建好边套个
看了鸟神博客,这里可以直接将所有距离保存在一个数组中,排序并去重,二分下标即可。这样快了很多很多!
hdu 2295 和这题一个套路,更裸一些。
跳舞链好强大,可惜只会用模板,这个讲的还挺清晰
代码:
/************************************************************************* > File Name: O.cpp > Author: jiangyuzhu > Mail: 834138558@qq.com > Created Time: Fri 08 Jul 2016 03:31:58 PM CST ************************************************************************/#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<map>using namespace std;#define sal(n) scanf("%I64d", &(n))#define sa(n) scanf("%d", &(n))typedef long long ll;const int maxn = 3600 + 5, maxc = 60 + 5, maxr = 60 + 5, inf = 0x3f3f3f3f;struct Node{ll x; ll y;}city[maxn];int L[maxn], R[maxn], D[maxn], U[maxn], C[maxn];int S[maxc], H[maxr], size;int n, m, k;ll d[maxr][maxc], t[maxn];///不需要S域void Link(int r, int c){ S[c]++; C[size] = c; U[size] = U[c]; D[U[c]] = size; D[size] = c; U[c] = size; U[c] = size; if(H[r] == -1) H[r] = L[size] = R[size] = size; else { L[size] = L[H[r]]; R[L[H[r]]] = size; R[size] = H[r]; L[H[r]] = size; } 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;}int h(){///用精确覆盖去估算剪枝 int ret = 0; bool vis[maxc]; memset (vis, false, sizeof(vis)); for(int i = R[0]; i; i = R[i]){ if(vis[i]) continue; ret++; vis[i] = true; for (int j = D[i]; j != i; j = D[j]) for (int k = R[j]; k != j; k = R[k]) vis[C[k]] = true; } return ret;}int ans;bool Dance(int a) //具体问题具体分析{ if(a + h() > k) return 0; if(!R[0]) return a <= k; int c = R[0]; for (int i = R[0]; 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(a + 1)) return 1; for (int j = L[i]; j != i; j = L[j]) resume(j); resume(i); } return 0;}void initL(int x)///col is 1~x,row start from 1{ for (int i = 0; i <= x; ++i){ S[i] = 0; D[i] = U[i] = i; L[i+1] = i; R[i] = i+1; }///对列表头初始化 R[x] = 0; size = x + 1;///真正的元素从m+1开始 memset (H, -1, sizeof(H)); ///mark每个位置的名字}ll dist(int i, int j){ ll d = abs(city[i].x - city[j].x) + abs(city[i].y - city[j].y); return d;}bool judge(ll mid){ initL(n); ans = 0x3f3f3f3f; for(int i = 1; i <= n; i++){ for(int j = 1; j <= n; j++){ if(d[i][j] <= mid){ Link(i, j); } } } return Dance(0);}int main (void){ int T;sa(T); for(int tt = 1; tt <= T; tt++){ sa(n);sa(k); ll maxd = 0; int cnt = 0; for(int i = 1; i <= n; i++){ scanf("%I64d%I64d", &city[i].x, &city[i].y); } for(int i = 1; i <= n; i++){ for(int j = 1; j <= n; j++){ d[i][j] = dist(i, j); t[cnt++] = d[i][j]; } } sort(t, t + cnt); int ncnt = unique(t, t + cnt) - t; ll l = -1, r = ncnt; while(r - l > 1){ ll mid = (l + r) / 2; if(judge(t[mid])) r = mid; else l = mid; } printf("Case #%d: %I64d\n", tt, t[r]); } return 0;}
0 0
- HDU 5046 Airport(DLX重复覆盖)
- hdu 5046 airport DLX可重复覆盖
- HDU 5046 Airport【DLX重复覆盖】
- HDU-5046 Airport(二分+DLX重复覆盖)
- HDU 5046 Airport (DLX可重复覆盖+二分)
- HDU 5046 Airport(二分+DLX重复覆盖)
- HDU 5046 Airport DLX多重覆盖
- DLX重复覆盖 hdu5046 Airport
- hdu 5046 Airport (重复覆盖)
- HDU 5046 Airport DLX
- 【HDU】5046 Airport 二分+重复覆盖
- HDU 5046 Airport ( Dancing Links 重复覆盖 )
- HDU 5046 Airport [DLX] [RepeatCover]
- HDU 3656 DLX重复覆盖
- HDU 3498 DLX 重复覆盖
- hdu 2295 DLX重复覆盖
- hdu 5046 Airport(Dancing Links重复覆盖)
- HDU 2295 Radar DLX重复覆盖
- Linux内核---56.gpio控制
- java 单链表基本操作--插入、删除、测长、打印
- U盘恢复(最后的最后还是量产)
- Java synchronized关键字详解
- 分布式系统的Quorum策略
- HDU 5046 Airport【DLX重复覆盖】
- LeetCode题解-230-Kth Smallest Element in a BST
- 谈谈document.ready和window.onload的区别
- Linux内核---57.sysfs的读写操作
- AppleScript入门
- shell 调用mysql 存储过程判断真假
- 301. Remove Invalid Parentheses
- Android组件----内容提供器Content Provider
- Unix网络编程之细节处理决定成败