可以重复的点覆盖, 写法和一般的DLX 很相似,但是在找到选择一行的时候,只删去这一行上所有点的列。   还要注意的是启发函数起了很大的剪枝作用。

Problem 1686 神龙的难题

Accept: 331    Submit: 1111 Time Limit: 1000 mSec    Memory Limit : 32768 KB

Problem Description

这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是个安宁的国家,人民安居乐业,魔物也比较少.但是.总有一些魔物不时会进入城市附近,干扰人民的生活.就要有一些人出来守护居民们不被魔物侵害.魔法使艾米莉就是这样的一个人.她骑着她的坐骑,神龙米格拉一起消灭干扰人类生存的魔物,维护王国的安定.艾米莉希望能够在损伤最小的前提下完成任务.每次战斗前,她都用时间停止魔法停住时间,然后米格拉他就可以发出火球烧死敌人.米格拉想知道,他如何以最快的速度消灭敌人,减轻艾米莉的负担.

Input

数据有多组,你要处理到EOF为止.每组数据第一行有两个数,n,m,(1<=n,m<=15)表示这次任务的地区范围. 然后接下来有n行,每行m个整数,如为1表示该点有怪物,为0表示该点无怪物.然后接下一行有两个整数,n1,m1 (n1<=n,m1<=m)分别表示米格拉一次能攻击的行,列数(行列不能互换),假设米格拉一单位时间能发出一个火球,所有怪物都可一击必杀.

Output

输出一行,一个整数,表示米格拉消灭所有魔物的最短时间.

Sample Input

4 4 1 0 0 1 0 1 1 0 0 1 1 0 1 0 0 1 2 2 4 4 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 2 2

Sample Output

4 1

Source

FOJ月赛-2009年2月- TimeLoop

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#define N 1000000
#define INF 0x3ffffff
int U[N],D[N],R[N],L[N],num[N],col[N],line[N],H[N];
int g[20][20],tg[250][250];;
int n,m;
int tn,tm;
int nn,mm;
int head;
int id;
int mi;void prepare()
{for(int i=0;i<=mm;i++){num[i]=0;U[i]=i;D[i]=i;R[i]=i+1;L[i+1]=i;}R[mm]=0;L[0]=mm;memset(H,-1,sizeof(H)); // 列的头指针
}void link(int n1,int m1)
{id++;++num[ line[id]=m1 ];col[id]=n1;D[id]=D[m1];U[ D[m1]]=id;U[id]=m1;D[m1]=id;if(H[n1]<0) H[n1]=L[id]=R[id]=id;else{L[ R[ H[n1] ] ]=id;R[id]=R[H[n1]];L[id]=H[n1];R[ H[n1] ]=id;}
}void build()
{id=mm;prepare();for(int i=0;i<=n-tn;i++){for(int j=0;j<=m-tm;j++){int flag=0;for(int i1=1;i1<=tn;i1++)for(int j1=1;j1<=tm;j1++){if(g[i+i1][j+j1]!=0){flag=1;link(nn,g[i+i1][j+j1]);}}nn++;}}
}void remove(int s)
{for(int i=D[s];i!=s;i=D[i]){L[R[i]]=L[i];R[L[i]]=R[i];}
}void resume(int s)
{for(int i=D[s];i!=s;i=D[i]){L[ R[i] ]=i;R[ L[i] ]=i;}
}/*int h() // 求出填满所有列所需的最小行
{int mark[N];memset(mark,0,sizeof(mark));}*/void print()
{memset(tg,0,sizeof(tg));for(int i=R[head];i!=head;i=R[i]){for(int j=D[i];j!=i;j=D[j])tg[col[j]][line[j]]=1;}for(int i=1;i<nn;i++){for(int j=1;j<=mm;j++)printf("%d ",tg[i][j]);printf("\n");}
}
int h()
{int mark[250];memset(mark,0,sizeof(mark));int sum=0;for(int i=R[head];i!=head;i=R[i]){if(mark[i]==0){sum++;mark[i]=1;for(int j=D[i];j!=i;j=D[j])for(int k=R[j];k!=j;k=R[k])mark[line[k]]=1;}}return sum;
}
void dfs(int s)
{if(s+h()>=mi) return ;if(R[head]==head){mi=s;return ;}int tmi=INF,tu;for(int i=R[head];i!=head;i=R[i]){if(num[i]<tmi){tmi=num[i];tu=i;}}for(int i=D[tu];i!=tu;i=D[i]){remove(i);for(int j=R[i];j!=i;j=R[j])remove(j);dfs(s+1);for(int j=L[i];j!=i;j=L[j])resume(j);resume(i);}
}int main()
{while(scanf("%d%d",&n,&m)!=EOF){head=0;nn=1;mm=0;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){scanf("%d",&g[i][j]);if(g[i][j]==1){mm++;g[i][j]=mm;}}scanf("%d%d",&tn,&tm);build();mi=INF;//print();dfs(0);printf("%d\n",mi);}return 0;
}

转载于:https://www.cnblogs.com/chenhuan001/archive/2013/04/08/3007292.html

fzu 1686(DLX 重复点覆盖)相关推荐

  1. FZU 1686 神龙的难题(DLX反复覆盖)

    FZU 1686 神龙的难题 题目链接 题意:中文题 思路:每个1看成列,每个位置作为左上角的矩阵看成行.dlx反复覆盖就可以 代码: #include <cstdio> #include ...

  2. hdu 2295 Radar DLX 重复覆盖问题

    http://acm.hdu.edu.cn/showproblem.php?pid=229 题意: 一个国家有n个城市,m个雷达,我们同时操作的雷达数最多为k,给出城市与国家的坐标,求小于等于k的操作 ...

  3. Acwing.379 捉迷藏(最小路径重复点覆盖)

    传送门 1.前置知识 1.最小路径点覆盖 DAG中选出最小数量的不相交路径(无公共点),将所有点覆盖. 求法:将DAG中的点拆成出点和入点,构成一个二分图. 则原图的最小路径点覆盖转化到新图中: 1. ...

  4. HDU 3498 whosyourdaddy DLX重复覆盖

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=3498 题意: 有 n n个敌人,其中有mm对敌人互为邻居,当你攻击杀死一个敌人时,同时会杀死它所有的邻居 ...

  5. FZU 1686 神龙的难题(重复覆盖问题舞蹈链)

    题目链接:[kuangbin带你飞]专题三 Dancing Links D - 神龙的难题 题意 Description 这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是 ...

  6. HDU 3498 whosyourdaddy(DLX重复覆盖)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3498         n个点,m条无向边,删除一个点会把与其相邻的点一起删掉,问最少删几次可以删掉所有 ...

  7. [DLX重复覆盖] hdu 3498 whosyourdaddy

    题意: 给N个怪,M个关系. 每个关系代表a和b是邻居. 然后问每次攻击你可以攻击一个怪以及它的全部邻居 问最少需要几次攻击能把怪全部杀死. 思路: 怪为行和列,然后对面每个怪的邻居都是这个怪的列建图 ...

  8. 估计人数【最小路径重复点覆盖】【直接在(i,j)建一个新点】

    估计人数 题意 思路 用最少的人,走完这几条线.最小重复路径点覆盖问题 建图之后,跑一下二分图. 考虑建图:图中'1'连着完下.或者右走.我们把图中所有的1编号,然后建图,然后floly,然后匈牙利. ...

  9. FZU - 1686 神龙的难题 (舞蹈链,可重覆盖)

    这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是个安宁的国家,人民安居乐业,魔物也比较少.但是.总有一些魔物不时会进入城市附近,干扰人民的生活.就要有一些人出来守护居民们 ...

最新文章

  1. 怎样学好python-如何学好python——致python初学者的天梯
  2. 035_jdbc-mysql-dbutils的使用
  3. LiveVideoStack线上分享第三季(十四):FLV封装格式介绍及解析
  4. redis管道的使用
  5. 做网页前端遇到的一些问题
  6. 电话号码的判断--使用正则表达式的示例
  7. 2017年9月27日日志
  8. 喂不饱的滴滴,也要撇开腾讯另立门户了
  9. shell脚本ssh登录并执行命令_Linux批量免密码SSH登录案例
  10. 判断拐点的条件_专业的交易者如何捕捉振荡区间的双向拐点。上篇
  11. matlab2c使用c++实现matlab函数系列教程-normstat函数
  12. 无需无线路由,将系统为win7的笔记本变成wifi的方法
  13. cgroup学习(四)——mount hierarchy
  14. java 代码走查_代码走查如何保证软件质量
  15. 自动化测试框架Selenium的使用——安装Selenium
  16. 输入N,打印对应N行的图案。
  17. PDF转换成Word转换器在线转换效果如何
  18. mac java 安装教程_MAC安装JDK详细教程
  19. 如何在Ubuntu 14.04中读取MOBI文件
  20. This computer doesn’t have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory“!

热门文章

  1. 2019第十二届“认证杯”数学建模(第二阶段)
  2. 搜索插件(django-haystack)
  3. c# 任务栏托盘图标鼠标进入MouseEnter和鼠标离开MouseLeave实现
  4. JQuery EasyUI学习框架
  5. 数据集成之主数据管理(一)基础概念篇
  6. 装完Windows 7后开启硬盘AHCI模式的方法
  7. [置顶] Activity启动流程
  8. Android学习日记(1)
  9. VC6.0 中的默认操作系统版本的问题
  10. Android AlarmManager 使用指南