fzu 1686(DLX 重复点覆盖)
可以重复的点覆盖, 写法和一般的DLX 很相似,但是在找到选择一行的时候,只删去这一行上所有点的列。 还要注意的是启发函数起了很大的剪枝作用。
![](/assets/blank.gif)
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
Sample Output
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 重复点覆盖)相关推荐
- FZU 1686 神龙的难题(DLX反复覆盖)
FZU 1686 神龙的难题 题目链接 题意:中文题 思路:每个1看成列,每个位置作为左上角的矩阵看成行.dlx反复覆盖就可以 代码: #include <cstdio> #include ...
- hdu 2295 Radar DLX 重复覆盖问题
http://acm.hdu.edu.cn/showproblem.php?pid=229 题意: 一个国家有n个城市,m个雷达,我们同时操作的雷达数最多为k,给出城市与国家的坐标,求小于等于k的操作 ...
- Acwing.379 捉迷藏(最小路径重复点覆盖)
传送门 1.前置知识 1.最小路径点覆盖 DAG中选出最小数量的不相交路径(无公共点),将所有点覆盖. 求法:将DAG中的点拆成出点和入点,构成一个二分图. 则原图的最小路径点覆盖转化到新图中: 1. ...
- HDU 3498 whosyourdaddy DLX重复覆盖
题目: http://acm.hdu.edu.cn/showproblem.php?pid=3498 题意: 有 n n个敌人,其中有mm对敌人互为邻居,当你攻击杀死一个敌人时,同时会杀死它所有的邻居 ...
- FZU 1686 神龙的难题(重复覆盖问题舞蹈链)
题目链接:[kuangbin带你飞]专题三 Dancing Links D - 神龙的难题 题意 Description 这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是 ...
- HDU 3498 whosyourdaddy(DLX重复覆盖)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3498 n个点,m条无向边,删除一个点会把与其相邻的点一起删掉,问最少删几次可以删掉所有 ...
- [DLX重复覆盖] hdu 3498 whosyourdaddy
题意: 给N个怪,M个关系. 每个关系代表a和b是邻居. 然后问每次攻击你可以攻击一个怪以及它的全部邻居 问最少需要几次攻击能把怪全部杀死. 思路: 怪为行和列,然后对面每个怪的邻居都是这个怪的列建图 ...
- 估计人数【最小路径重复点覆盖】【直接在(i,j)建一个新点】
估计人数 题意 思路 用最少的人,走完这几条线.最小重复路径点覆盖问题 建图之后,跑一下二分图. 考虑建图:图中'1'连着完下.或者右走.我们把图中所有的1编号,然后建图,然后floly,然后匈牙利. ...
- FZU - 1686 神龙的难题 (舞蹈链,可重覆盖)
这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是个安宁的国家,人民安居乐业,魔物也比较少.但是.总有一些魔物不时会进入城市附近,干扰人民的生活.就要有一些人出来守护居民们 ...
最新文章
- 怎样学好python-如何学好python——致python初学者的天梯
- 035_jdbc-mysql-dbutils的使用
- LiveVideoStack线上分享第三季(十四):FLV封装格式介绍及解析
- redis管道的使用
- 做网页前端遇到的一些问题
- 电话号码的判断--使用正则表达式的示例
- 2017年9月27日日志
- 喂不饱的滴滴,也要撇开腾讯另立门户了
- shell脚本ssh登录并执行命令_Linux批量免密码SSH登录案例
- 判断拐点的条件_专业的交易者如何捕捉振荡区间的双向拐点。上篇
- matlab2c使用c++实现matlab函数系列教程-normstat函数
- 无需无线路由,将系统为win7的笔记本变成wifi的方法
- cgroup学习(四)——mount hierarchy
- java 代码走查_代码走查如何保证软件质量
- 自动化测试框架Selenium的使用——安装Selenium
- 输入N,打印对应N行的图案。
- PDF转换成Word转换器在线转换效果如何
- mac java 安装教程_MAC安装JDK详细教程
- 如何在Ubuntu 14.04中读取MOBI文件
- This computer doesn’t have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory“!