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> ...
随机推荐
- 五子棋-b
五子棋是程序猿比较熟悉的一款小游戏,相信很多人大学时期就用多种语言写过五子棋小游戏.笔者工作闲暇之余,试着用OC实现了一下,在这里给大家分享一下.有不足之处,欢迎大家提供建议和指点!!!GitHub源 ...
- log的6种等级
在Java中,log有6种等级,从低到高为: (1)TRACE:用于展现程序执行的轨迹 (2)DEBUG:用于协助低层次的调试 (3)INFO:用于基本高层次的诊断信息,在长时间运行的代码段开始运行及 ...
- docker安装caffe
[最近一直想要学习caffe,但是苦苦纠结于环境安装不上,真的是第一步都迈不出去,还好有docker的存在!下面,对本人如何利用docker安装caffe做以简单叙述,不属于教程,只是记录自己都做了什 ...
- canvas仿黑客帝国的字符下落
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 ...
- Java多线程初学者指南(11):使用Synchronized块同步方法
synchronized关键字有两种用法.第一种就是在<使用Synchronized关键字同步类方法>一文中所介绍的直接用在方法的定义中.另外一种就是synchronized块.我们不仅可 ...
- GRUB引导——menu.lst的写法
转自menu.lst的写法.menu.lst的写法 1.menu.lst的写法之一 首先我们看一下我的Fedora 4.0 中的/boot/grub/menu.lst 的内容: default=0 ...
- Android 实现ListView异步加载图片
ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,下面就说实现方法,先贴上主方法的代码: package cn.wangmeng.test; ...
- 'dependencies.dependency.(groupId:artifactId:type:classifier)' must be unique
2016-10-09 23:14:43.177 DEBUG [restartedMain][org.springframework.core.type.classreading.AnnotationA ...
- Linux kernel get_prng_bytes函数数字错误漏洞
漏洞名称: Linux kernel get_prng_bytes函数数字错误漏洞 CNNVD编号: CNNVD-201310-142 发布时间: 2013-10-11 更新时间: 2013-10-1 ...
- 面向中国 Azure 开发者发布开源解决方案指南
发布于 2014-05-23 作者 刘 天栋 Azure 是一个开放.灵活的云平台,可支持大量且不断增长的开源应用程序.框架和语言.微软及微软开放技术通过与全球及中国本地的开源社区不懈地合作,将 ...