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> ...
随机推荐
- iOS 9 适配
一.iOS9 bitcode首先最大的问题就是坑货xcode7,xcode7默认是打开bitcode的,bitcode是苹果为了解决他自己以后的应用可以随意更换硬件的处理做的准备也就是arm指令集和x ...
- 【转载】TCP保活(TCP keepalive)
下图是我遇到tcp keepalive的例子: 以下为转载: TCP保活的缘起 双方建立交互的连接,但是并不是一直存在数据交互,有些连接会在数据交互完毕后,主动释放连接,而有些不会,那么在长时间无数据 ...
- 存储过程&Function
存储过程&Function 编号 类别 ORACLE MYSQL 注释 1 创建存储过程语句不同 create or replace procedure P_ADD_FAC( id_fac ...
- bzoj 2251: [2010Beijing Wc]外星联络 后缀数组
2251: [2010Beijing Wc]外星联络 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 424 Solved: 232[Submit][ ...
- bzoj 1138: [POI2009]Baj 最短回文路 dp优化
1138: [POI2009]Baj 最短回文路 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 161 Solved: 48[Submit][Sta ...
- 设计模式之观察者(Observer)模式 代码详解
import java.util.ArrayList; import java.util.List; /** * User: HYY * Date: 13-10-28 * Time: 下午1:34 * ...
- 转贴:C++中指针和引用的区别
从概念上讲.指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变. 而引用是一个别名,它在逻辑上不是独立的,它的存在具有 ...
- struts一点心得
action中: 设置属性并增加get,set方法,给属性赋值后 (如: private String name; public String getName() { return name; } p ...
- 一点一点学ASP.NET系列
转自:http://www.cnblogs.com/stwyhm/archive/2006/08/10/473075.html 做开发近两年了,自认为自己还算是个知道要上进的人,每天不停地学习,不停地 ...
- JDBC初步 JDBC连接SQLServer 2008之心路历程
转自:http://www.cnblogs.com/weilengdeyu/archive/2013/01/17/2864321.html JDBC简介 今天,研究了下JDBC连接SQL Server ...