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> ...
随机推荐
- Hibernate一对一双向关联(外键)
网站上各种搜索,都是一些清晰或者不清晰的例子,但是用下来一是确实不给力,二是完全不知道所以然. 后来终于在书中查到了就在这里记一下. 首先要说明,这里只解释双向一对一只有一个表里面有外键的情况. 就以 ...
- 关于Java(JDBC连接数据库)
Processing SQL Statements with JDBC 处理JDBC中的SQL语句 这节主要是 JDBC 与数据库交互的基本步骤 JDBC的基石是DriverManager,通过它,J ...
- JQuery replace 替换全部
天在做写个程序时遇到需要替换的功能,可是一开始用jquery的replace时,发现只替换到第一个.最后没办法,只好用正则表达式来例如下面 re = new RegExp("{thisc ...
- 思考 Swift 中的 MirrorType 协议
Swift中的反射非常有限,仅允许以只读方式访问元数据的类型子集.或许 Swift 因有严格的类型检验而不需要反射.编译时已知各种类型,便不再需要进行进一步检查或区分.然后大量的 Cocoa API ...
- 【网络流24题】No.9 方格取数问题 (二分图点权最大独立集)
[题意] 在一个有 m*n 个方格的棋盘中, 每个方格中有一个正整数. 现要从方格中取数, 使任意 2 个数所在方格没有公共边,且取出的数的总和最大.试设计一个满足要求的取数算法. 输入文件示例inp ...
- win7+ubuntu双系统安装攻略
一1.下载分区软件,为ubuntu安装分出一个区 2.磁盘管理器,选中该区,右键,删除卷,该区变为绿色,成为空闲区 3.成功 二为ubunt添加开机导引项 1,安装好easybcd2.0后,启动软件: ...
- Qt源码分析之QPointer
QPointer是一个指针封装类,其作用类似于智能指针,但是它最大的特点应该是在指针的控制上,它希望一个Qt的指针(当然是从QObject派生的)可以同时被多个类拥有,这在界面编程中当然是很常见的事情 ...
- Android ViewDragHelper源码解析
在自定义ViewGroup的过程中,如果涉及到View的拖动滑动,ViewDragHelper的使用应该是少不了的,它提供了一系列用于用户拖动子View的辅助方法和相关的状态记录,像Navigatio ...
- Chapter 17 Replication
Chapter 17 Replication Table of Contents 17.1 Replication Configuration 17.2 Replication Implementat ...
- (转载)JavaScript中的原型和对象机制
(转载)http://www.cnblogs.com/FlyingCat/archive/2009/09/21/1570656.html 1 对象相关的一些语言特性 1.1 一切皆为对象JavaScr ...