这一道题和HDU2295是一样

是一个dancing links重复覆盖解决最小支配集的问题

在给定长度下求一个最小支配集,只要小于k就行

然后就是二分答案,每次求最小支配集

只不过HDU2295是浮点,这里是整数

我写的一个比较暴力

#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef long long LL;
const int N=4e3;
int n,m,sz,k;
int u[N],l[N],r[N],d[N];
int h[],s[],col[N];
void init()
{
for(int i=; i<=m; ++i)
{
s[i]=;
u[i]=d[i]=i;
l[i]=i-;
r[i]=i+;
}
r[m]=;
l[]=m;
sz=m;
for(int i=; i<=n; ++i)
h[i]=-;
}
void link(int x,int y)
{
++sz;
++s[y],col[sz]=y;
u[sz]=u[y],d[u[y]]=sz;
d[sz]=y,u[y]=sz;
if(h[x]==-)h[x]=l[sz]=r[sz]=sz;
{
l[sz]=l[h[x]];
r[l[h[x]]]=sz;
r[sz]=h[x];
l[h[x]]=sz;
}
}
void del(int y)
{
for(int i=d[y]; i!=y; i=d[i])
r[l[i]]=r[i],l[r[i]]=l[i];
}
void resume(int y)
{
for(int i=d[y]; i!=y; i=d[i])
r[l[i]]=l[r[i]]=i;
}
bool vis[];
int f()
{
int ret=;
for(int i=r[]; i; i=r[i])
vis[i]=;
for(int i=r[]; i; i=r[i])
{
if(vis[i])continue;
vis[i]=;
++ret;
for(int j=d[i]; j!=i; j=d[j])
for(int k=r[j]; k!=j; k=r[k])
vis[col[k]]=;
}
return ret;
}
bool dance(int pos)
{
if(pos+f()>k)return ;
if(!r[])
{
if(pos<=k) return ;
return ;
}
int t=r[];
for(int i=r[]; i!=; i=r[i])
if(s[i]<s[t])t=i;
for(int i=d[t]; i!=t; i=d[i])
{
del(i);
for(int j=r[i]; j!=i; j=r[j])
del(j);
if(dance(pos+))return ;
for(int j=l[i]; j!=i; j=l[j])
resume(j);
resume(i);
}
return ;
}
struct point
{
LL x,y;
}o[];
LL ABS(LL x,LL y)
{
if(x>=y)return x-y;
return y-x;
}
LL dis(point a,point b)
{
return ABS(a.x,b.x)+ABS(a.y,b.y);
}
LL D[N];
int main()
{
int T,cas=;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k),m=n;
for(int i=;i<=n;++i)
scanf("%I64d%I64d",&o[i].x,&o[i].y);
int cnt=;
for(int i=;i<=n;++i)
for(int j=i;j<=n;++j)
D[++cnt]=dis(o[i],o[j]);
sort(D+,D++cnt);
cnt=unique(D+,D++cnt)-D-;
int high=cnt,low=,mid;
while(low<high)
{
mid=(low+high)>>;
init();
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
if(dis(o[i],o[j])<=D[mid])
link(i,j);
if(dance())high=mid;
else low=mid+;
}
printf("Case #%d: %I64d\n",++cas,D[low]);
}
return ;
}

然后另一个是离散化的

#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef long long LL;
const int N=4e3;
int n,m,sz,k;
int u[N],l[N],r[N],d[N];
int h[],s[],col[N];
void init()
{
for(int i=; i<=m; ++i)
{
s[i]=;
u[i]=d[i]=i;
l[i]=i-;
r[i]=i+;
}
r[m]=;
l[]=m;
sz=m;
for(int i=; i<=n; ++i)
h[i]=-;
}
void link(int x,int y)
{
++sz;
++s[y],col[sz]=y;
u[sz]=u[y],d[u[y]]=sz;
d[sz]=y,u[y]=sz;
if(h[x]==-)h[x]=l[sz]=r[sz]=sz;
{
l[sz]=l[h[x]];
r[l[h[x]]]=sz;
r[sz]=h[x];
l[h[x]]=sz;
}
}
void del(int y)
{
for(int i=d[y]; i!=y; i=d[i])
r[l[i]]=r[i],l[r[i]]=l[i];
}
void resume(int y)
{
for(int i=d[y]; i!=y; i=d[i])
r[l[i]]=l[r[i]]=i;
}
bool vis[];
int f()
{
int ret=;
for(int i=r[]; i; i=r[i])
vis[i]=;
for(int i=r[]; i; i=r[i])
{
if(vis[i])continue;
vis[i]=;
++ret;
for(int j=d[i]; j!=i; j=d[j])
for(int k=r[j]; k!=j; k=r[k])
vis[col[k]]=;
}
return ret;
}
bool dance(int pos)
{
if(pos+f()>k)return ;
if(!r[])
{
if(pos<=k) return ;
return ;
}
int t=r[];
for(int i=r[]; i!=; i=r[i])
if(s[i]<s[t])t=i;
for(int i=d[t]; i!=t; i=d[i])
{
del(i);
for(int j=r[i]; j!=i; j=r[j])
del(j);
if(dance(pos+))return ;
for(int j=l[i]; j!=i; j=l[j])
resume(j);
resume(i);
}
return ;
}
struct point
{
LL x,y;
}o[];
LL ABS(LL x,LL y)
{
if(x>=y)return x-y;
return y-x;
}
LL dis(point a,point b)
{
return ABS(a.x,b.x)+ABS(a.y,b.y);
}
LL D[N];
int main()
{
int T,cas=;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k),m=n;
for(int i=;i<=n;++i)
scanf("%I64d%I64d",&o[i].x,&o[i].y);
int cnt=;
for(int i=;i<=n;++i)
for(int j=i;j<=n;++j)
D[++cnt]=dis(o[i],o[j]);
sort(D+,D++cnt);
cnt=unique(D+,D++cnt)-D-;
int high=cnt,low=,mid;
while(low<high)
{
mid=(low+high)>>;
init();
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
if(dis(o[i],o[j])<=D[mid])
link(i,j);
if(dance())high=mid;
else low=mid+;
}
printf("Case #%d: %I64d\n",++cas,D[low]);
}
return ;
}

HDU5046 Airport dancing links 重复覆盖+二分的更多相关文章

  1. HDU 2295 Radar (二分 + Dancing Links 重复覆盖模型 )

    以下转自 这里 : 最小支配集问题:二分枚举最小距离,判断可行性.可行性即重复覆盖模型,DLX解之. A*的启发函数: 对当前矩阵来说,选择一个未被控制的列,很明显该列最少需要1个行来控制,所以ans ...

  2. HDU 3335 Divisibility dancing links 重复覆盖

    分析: dlx重复覆盖的巧用,重复覆盖的原理恰好符合本题的筛选方式,即选择一个数后,该数的倍数或约数可以保证在之后的搜索中不会被选择 于是修改一下启发函数,求解最大的重复覆盖即可.   其实不一定不被 ...

  3. HDU 2295 Radar dancing links 重复覆盖

    就是dancing links 求最小支配集,重复覆盖 精确覆盖时:每次缓存数据的时候,既删除行又删除列(这里的删除列,只是删除表头) 重复覆盖的时候:只删除列,因为可以重复覆盖 然后重复覆盖有一个估 ...

  4. HDU 5046 Airport ( Dancing Links 反复覆盖 )

    今年上海网络赛的一道题目 , 跟 HDU 2295 如出一辙 . 就是距离的计算一个是欧几里得距离 , 一个是曼哈顿距离 学完DLX感觉这题好水 ,就是一个裸的反复覆盖 注意下别溢出即可了 #incl ...

  5. FZU1686 神龙的难题 dancing links 重复覆盖

    分析:每次可以打一个小矩阵的怪,然后把每个怪看成一列,然后每个小矩阵看成一行,枚举左上角就行 注:然后注意总共的节点数是新图的行*列的个数,不是原图 #include<cstdio> #i ...

  6. hdu5046(重复覆盖+二分)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5046 题意:要在n个城市里建造不超过k个机场覆盖所有城市,问机场城市之间最大距离最小为多少. 分析:二 ...

  7. hdu3656Fire station(DLX重复覆盖 + 二分)

    题目请戳这里 题目大意:一个城市n个点,现在要建m个消防站,消防站建在给定的n个点中.求建m个消防站后,m个消防站要覆盖所有的n个点的覆盖半径最小. 题目分析:重复覆盖问题,DLX解决.不过要求覆盖半 ...

  8. 【转】Dancing Links精确覆盖问题

    原文链接:http://sqybi.com/works/dlxcn/ (只转载过来一部分,全文请看原文,感觉讲得很好~)正文    精确覆盖问题    解决精确覆盖问题    舞蹈步骤    效率分析 ...

  9. hihoCoder #1321 : 搜索五•数独 (Dancing Links ,精确覆盖)

    hiho一下第102周的题目. 原题地址:http://hihocoder.com/problemset/problem/1321 题意:输入一个9*9数独矩阵,0表示没填的空位,输出这个数独的答案. ...

随机推荐

  1. dive into python 读笔(1)

    chapter2 and 3: 使用Python IDE来交互式地测试表达式 编写Python程序并且从IDE运行,或者从命令行运行 导入模块及调用它们的函数 声明函数以及doc string.局部变 ...

  2. 【BZOJ 2875】 [Noi2012]随机数生成器

    Description  给你6个数,m, a, c, x0, n, g Xn+1 = ( aXn + c ) mod m,求Xn m, a, c, x0, n, g<=10^18 Input ...

  3. linux mint 五笔安装方法

    终于可以使用五笔了,方法就是安装好ibus后要设置首选项,这样在首选项里设置就可以了.

  4. C#中结构体与字节流互相转换

    1.定义与C++对应的C#结构体 在c#中的结构体不能定义指针,不能定义字符数组,只能在里面定义字符数组的引用. C++的消息结构体如下: //消息格式 4+16+4+4= 28个字节 struct ...

  5. linux 安装firefox

    从火狐官网下载的firefox-9.0.1.tar.bz2解压后,进入firefox文件夹,执行./firefox会提示缺少库,故采用yum安装Firefox9.1.切换到root用户 su - 2. ...

  6. @Entity设置OneToMany

    Hibernate设置bean映射数据库的方式有配置模式与注解模式,下面通过注解模式配置OneToMany @Entity @Table(name="csdnbbs_sys_catalog& ...

  7. Linux中的MyEclipse配置Hadoop

    一.所需软件 注意:安装MyEclipse后,我再已安装软件里找不到MyEclipse,所以我在root权限下用命令行启动MyEclipse,貌似避免了很多权限问题. sudo su 输入密码 cd ...

  8. POJ2528+线段树

    见代码. /* 线段树+Lazy 题意:有一面墙,被等分为1QW份,一份的宽度为一个单位宽度. 现在往墙上贴N张海报,每张海报的宽度是任意的,但是必定是单位宽度的整数倍,且<=1QW. 后贴的海 ...

  9. QPushButton 的checkable 属性

    只有setCheckable(true),这个button才能发射 toggle(bool) 信号. 而toggle(bool)代表了button 按下,弹起的状态像0,1的切换开关.

  10. SRM588

    250: 有n首歌每首歌有duration和tone,连续唱m首歌会消耗每首歌的duration以及相邻两首歌的tone的差的绝对值的和,给个T,问说在T时间内最对能唱多少歌. 将歌按tone排序后发 ...