HDU 5046 Airport ( Dancing Links 反复覆盖 )
今年上海网络赛的一道题目 , 跟 HDU 2295 如出一辙 。 就是距离的计算一个是欧几里得距离 , 一个是曼哈顿距离
学完DLX感觉这题好水 ,就是一个裸的反复覆盖
注意下别溢出即可了
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <math.h>
#include <stdlib.h>
using namespace std; const int maxn = 60 + 10 ;
const int maxr = 60 + 10 ;
const int maxnode = 60 * 60 + maxr + 10 ; #define FOR( i , A , s ) for( int i = A[s] ; i != s ; i = A[i] ) struct DLX{
// maxn 列数 , maxnode 总节点数 , maxr 行数
int n , sz ;
int S[maxn] ; int row[maxnode] , col[maxnode] ;
int L[maxnode] , R[maxnode] , U[maxnode] , D[maxnode] ;
int H[maxr] ; int ansd , ans[maxr] ; void init( int N ) {
n = N ;
// 第一行的虚拟结点
for( int i = 0 ; i <= n ; i ++ ) {
U[i] = D[i] = i ;
L[i] = i - 1 ;
R[i] = i + 1 ;
}
R[n] = 0 ; L[0] = n ;
sz = n + 1 ;
// 每一列的个数
memset( S , 0 , sizeof(S) ) ;
// H[i] = -1 表示这一行还没有 1
// 否则表示第一个 1 的 sz 是多少
memset( H , -1 , sizeof(H)) ;
} // 在第r行第c列加入一个1
void Link( int r , int c ) {
row[sz] = r ;
col[sz] = c ;
S[c] ++ ; D[sz] = c ; U[sz] = U[c] ;
D[U[c]] = sz ; U[c] = sz ; if( H[r] < 0 ) { H[r] = L[sz] = R[sz] = sz ; }
else{
R[sz] = H[r] ;
L[sz] = L[H[r]] ;
R[L[sz]] = sz ;
L[R[sz]] = sz ;
} sz ++ ; } // 删除 第 c 列
void remove ( int c ) {
FOR( i , D , c ) {
L[R[i]] = L[i] ;
R[L[i]] = R[i] ;
}
} // 恢复第 c 列
void restore( int c ) {
FOR( i , D , c ) {
L[R[i]] = R[L[i]] = i ;
}
} bool vis[maxn] ; int f() {
int ans = 0 ;
FOR( i , R , 0 ) vis[i] = true ;
FOR( i , R , 0 ) {
if( vis[i] ) {
vis[i] = false ;
ans ++ ;
FOR( j , D , i )
FOR( k , R , j )
vis[col[k]] = false ;
}
}
return ans ;
} bool dfs( int d ) {
// 剪枝
if( d + f() > best ) return false ;
// R[0] = 0 表示找到一个可行解
if( R[0] == 0 ) return d <= best ;
// 找到 s 最小的列 , 加快搜索的速度
int c = R[0] ;
FOR( i , R , 0 )
if( S[i] < S[c] ) c = i ;
FOR( i , D , c ) {
remove(i);
FOR( j , R , i ) remove( j );
if (dfs(d + 1))
return true ;
FOR( j , R , i ) restore( j ) ;
restore( i ) ;
}
return false ;
} bool solve( int k ) {
best = k ;
return dfs(0) ;
}
int best ;
} dlx ; int n , m , k ;
__int64 ABS( __int64 x ) {
return x < 0 ? -x : x ;
} struct Point{
__int64 x , y ;
void get(){
scanf( "%I64d%I64d" , &x , &y ) ;
} friend __int64 dist ( const Point &a , const Point & b ) {
return ABS( a.x - b.x ) + ABS ( a.y - b.y ) ;
}
}; Point city[65] ; __int64 dis[60*60+10] ; int lisanhua( int Index ) {
int cnt = 1 ;
for( int i = 1 ; i < Index ; i ++ ) {
if( dis[i] != dis[i-1] )
dis[cnt++] = dis[i] ;
}
return cnt - 1 ;
} int main(){
int cas ;
int casn = 1 ;
scanf( "%d" , &cas ) ;
while( cas -- ) {
scanf( "%d%d" , &n, &k ) ;
for( int i = 1 ; i <= n ; i ++ ) {
city[i].get() ;
}
int Index = 0 ;
for( int i = 1 ; i <= n ; i ++ ) {
for( int j = i ; j <= n ; j ++ ) {
dis[Index++] = dist( city[i] , city[j] ) ;
}
}
sort( dis , dis + Index ) ;
Index = lisanhua( Index ) ;
__int64 l = 0 , r = Index ;
__int64 mid ;
while( l < r ) {
mid = ( l + r ) / 2 ;
dlx.init( n ) ;
for( int i = 1 ; i <= n ; i ++ ) {
for( int j = 1 ; j <= n ; j ++ ) {
if( dist( city[i] , city[j] ) <= dis[mid] ) {
dlx.Link( i , j ) ;
}
}
}
if( dlx.solve( k ) ) {
r = mid ;
}else{
l = mid + 1 ;
}
}
printf( "Case #%d: %I64d\n" , casn ++ , dis[l] ) ;
}
return 0 ;
}
HDU 5046 Airport ( Dancing Links 反复覆盖 )的更多相关文章
- HDU 5046 Airport(DLX反复覆盖)
HDU 5046 Airport 题目链接 题意:给定一些机场.要求选出K个机场,使得其它机场到其它机场的最大值最小 思路:二分+DLX反复覆盖去推断就可以 代码: #include <cstd ...
- HDU5046 Airport dancing links 重复覆盖+二分
这一道题和HDU2295是一样 是一个dancing links重复覆盖解决最小支配集的问题 在给定长度下求一个最小支配集,只要小于k就行 然后就是二分答案,每次求最小支配集 只不过HDU2295是浮 ...
- HDU 3335 Divisibility dancing links 重复覆盖
分析: dlx重复覆盖的巧用,重复覆盖的原理恰好符合本题的筛选方式,即选择一个数后,该数的倍数或约数可以保证在之后的搜索中不会被选择 于是修改一下启发函数,求解最大的重复覆盖即可. 其实不一定不被 ...
- HDU 2295 Radar dancing links 重复覆盖
就是dancing links 求最小支配集,重复覆盖 精确覆盖时:每次缓存数据的时候,既删除行又删除列(这里的删除列,只是删除表头) 重复覆盖的时候:只删除列,因为可以重复覆盖 然后重复覆盖有一个估 ...
- HDU 5046 Airport【DLX重复覆盖】
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5046 题意: 给定n个城市的坐标,要在城市中建k个飞机场,使城市距离最近的飞机场的最长距离最小,求这 ...
- HDU 3111 Sudoku ( Dancing Links 精确覆盖模型 )
推荐两篇学DLX的博文: http://bbs.9ria.com/thread-130295-1-1.html(这篇对DLX的工作过程演示的很详细) http://yzmduncan.iteye.co ...
- 【转】Dancing Links精确覆盖问题
原文链接:http://sqybi.com/works/dlxcn/ (只转载过来一部分,全文请看原文,感觉讲得很好~)正文 精确覆盖问题 解决精确覆盖问题 舞蹈步骤 效率分析 ...
- 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> ...
随机推荐
- bzoj 1068: [SCOI2007]压缩 DP
1068: [SCOI2007]压缩 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 496 Solved: 315[Submit][Status] D ...
- C++开发与Windows API
Windows API 向 C++ 开发人员提出了一项挑战. 组成 API 的众多库大都表现为 C 语言风格的函数和句柄或是 COM 风格的接口. 这些用起来都不太方便,需要进行一定的封装或间接操作. ...
- [OJ] Lowest Common Ancestor
LintCode 88. Lowest Common Ancestor (Medium) LeetCode 236. Lowest Common Ancestor of a Binary Tree ( ...
- ruby hashtable散列表
dict={'cat'=>'abc','dog'=>'def'}puts dict.size dict.keys返回所有的key, values返回所有的value. 删除: dict.d ...
- 行为树实现AI逻辑
http://blog.csdn.net/kenkao/article/details/6099966 http://www.aisharing.com/archives/99 http://www. ...
- 17.1.1 How to Set Up Replication 设置复制:
17.1.1 How to Set Up Replication 设置复制: 17.1.1.1 Setting the Replication Master Configuration 17.1.1. ...
- Makefile第三讲:终端传值给Makefile、Makefile传值给C++代码
摘要 终端传值给Makefile,咋传?只需在终端输入以下命令,那么就可以在Makefile文件中放心大担的使用$(abcde)这个变量了,它的值为BBB Makefile fun.h #includ ...
- RatingBar设置显示星星个数
RatingBar评分控件 项目中遇到问题 marker一下: 关于自定义以及遇到的出现模糊情况 多半是因为切得图除颜色外 不一致的原因 如果大小也不一样,(沃日) 问题是这样的: 我可以通过OnRa ...
- response常见应用、response细节、输出随机图片、定时刷新网页
response常见应用 向客户端输出中文数据 分别以OutputStream和PrintWriter输出 多学一招:使用HTML语言里面的<meta>标签来控制浏览器行为 思考:用O ...
- HDU1394-Minimum Inversion Number
http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number Time Limit: 2000/1000 MS (Ja ...