题意:有一个英雄,他有一个技能,可以使一个点和与他相邻的点受到伤害,问最少攻击几个点可以使所有点至少被伤害一次。

思路:DLX。很裸。设行为每一个点,列为攻击点,在这里行元素与列元素都为n。然后DLX+迭代加深的启发式搜索就可以了,而启发式函数的含义为在当前状态下,在最优情况中,需要攻击几个点来消灭所有点。设计为选取一列控制,这时需要一行,行数加1。并且将与它连接的所有行包含的列都控制,这个只有在最理想情况才能达到的,因为很少出现一行可以控制这一列上所有行控制的列。在这里证明一下启发式函数hh()的单调不减性。因为每次至多只能删除一列,且根据设计要删除的列之间是无关联的,所以只存在两种情况,要么删除一列,要么不删除,而g()为迭代深度,每次都加1,且hh()最多减1,所以满足不减性。

启发式函数:

int hh()
{int ret=0;memset(hash,0,sizeof(hash));for(int i=dlx[head].r; i!=head; i=dlx[i].r){if(hash[i]==false){hash[i]=true;ret++;for(int j=dlx[i].d; j!=i; j=dlx[j].d)for(int k=dlx[j].r; k!=j; k=dlx[k].r){hash[dlx[k].c]=true;}}}return ret;
}

代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn=15000;
struct node
{int l,r;int u,d;int s,c;
};//十字链表元素,u,d,l,r为上,下,左,右,s为列大小,c为元素所在的列主元。
node dlx[maxn];
int res[60][5];
int n,m;
bool map[60][60];
int size;
int h[60];//行首元
bool hash[60];
int head;//表头
int limit;//迭代限制
void init(int r,int c)//初始化列首元
{head=0;for(int i=0; i<=c; i++){dlx[i].s=0;dlx[i].u=dlx[i].d=i;dlx[i].r=i+1;dlx[i+1].l=i;}size=c;dlx[c].r=0;while(r){h[r--]=-1;}
}
void link(int r,int c)//将元素插入r行,c 列
{int tmp=++size;dlx[c].s++;dlx[tmp].c=c;dlx[tmp].d=dlx[c].d;dlx[tmp].u=c;dlx[dlx[c].d].u=tmp;dlx[c].d=tmp;if(h[r]<0){h[r]=dlx[tmp].l=dlx[tmp].r=tmp;}else{dlx[tmp].r=dlx[h[r]].r;dlx[tmp].l=h[r];dlx[dlx[h[r]].r].l=tmp;dlx[h[r]].r=tmp;}
}
void remove(int x)
{for(int i=dlx[x].d; i!=x; i=dlx[i].d){dlx[dlx[i].r].l=dlx[i].l;dlx[dlx[i].l].r=dlx[i].r;dlx[dlx[i].c].s--;}
}
void resume(int x)
{for(int i=dlx[x].u; i!=x; i=dlx[i].u){dlx[dlx[i].r].l=i;dlx[dlx[i].l].r=i;dlx[dlx[i].c].s++;}
}
int hh()//估价函数
{int ret=0;memset(hash,0,sizeof(hash));for(int i=dlx[head].r; i!=head; i=dlx[i].r){if(hash[i]==false){hash[i]=true;ret++;for(int j=dlx[i].d; j!=i; j=dlx[j].d)for(int k=dlx[j].r; k!=j; k=dlx[k].r){hash[dlx[k].c]=true;}}}//cout<<"er"<<endl;return ret;
}
bool dlx_dfs(int k)//dancing links搜索
{if(k+hh()>=limit){return false;}if(dlx[head].r==head){if(k<limit) limit=k;return true;}int minn=n+1;int tt;for(int i=dlx[head].r; i!=head; i=dlx[i].r){if(minn>dlx[i].s){minn=dlx[i].s;tt=i;}}for(int i=dlx[tt].d; i!=tt; i=dlx[i].d){remove(i);for(int j=dlx[i].r; j!=i; j=dlx[j].r){remove(j);}if(dlx_dfs(k+1)){return true;}for(int j=dlx[i].l; j!=i; j=dlx[j].l){resume(j);}resume(i);}return false;
}
int astar()// 迭代加深A*
{limit=hh();//  cout<<limit<<endl;while(dlx_dfs(0)==false) limit++;return limit;
}
int main()
{// freopen("in.txt","r",stdin);while(~scanf("%d%d",&n,&m)){init(n,n);memset(map,0,sizeof(map));for(int i=0; i<m; i++){int a,b;scanf("%d%d",&a,&b);map[a][b]=map[b][a]=1;}for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){if(map[i][j]||i==j)//这里加上i本身被自己摧毁{link(i,j);}}int ans=astar();dlx_dfs(0);printf("%d\n",ans);}return 0;
}

hdu 3498 whosyourdaddy (重复覆盖,DLX+迭代加深A*)相关推荐

  1. hdu 3498 whosyourdaddy 重复覆盖

    #include <bits/stdc++.h> using namespace std; struct DLX {const static int maxn=64,maxm=64,max ...

  2. 【HDU】3498 whosyourdaddy 重复覆盖入门题

    传送门:[HDU]3498 whosyourdaddy 题目分析:重复覆盖入门题. 重复覆盖相对于精确覆盖有些地方不同,精确覆盖每次可以删除多行多列,但是重复覆盖每次只能删除一行多列,而且还需要可行性 ...

  3. hdu - 3498 - whosyourdaddy(重复覆盖DLX)

    题意:N(2 ≤ N ≤ 55)个点,M(0 ≤ M ≤ N*N)条无向边,删除一个点会把与其相邻的点一起删掉,问最少删几次可以删掉所有点. 题目链接:http://acm.hdu.edu.cn/sh ...

  4. HDU 3498 whosyourdaddy DLX重复覆盖

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

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

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

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

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

  7. HDU 3498 whosyourdaddy(Dancing_Links重复覆盖)

    题目地址 题意:给你n个城市,m条道路,每次摧毁一个城市会附带把与它直接连接的城市的摧毁,一个城市可以重复摧毁(如果不能重复就是精确覆盖了),问你最少摧毁多少个城市能把所有城市摧毁. 思路:我们可以构 ...

  8. HDU 4398 whosyourdaddy 精确覆盖,允许重复覆盖

    题目大意:有n个点,其中一些点是相连的.领主的攻击具有溅射,即攻击一个点,此点相邻的点也会收到攻击.问,领主最少攻击多少次,使得每个点都至少被攻击一次. 与传统精确覆盖相比,此题允许重复覆盖.那么,我 ...

  9. hdu 3498 whosyourdaddy

    Dancing Links 重复覆盖问题~ 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3498 这两天学习了Dancing Links  ,它主要 ...

最新文章

  1. 注册表----修改Win7登录界面
  2. 海康威视人证对比设备SDK-C#
  3. html显示数据库表格asp,ASP实现在WEB中显示电子表格数据 显示数据及生成HTML表格...
  4. BCB key事件中判断Shift、Alt、Ctrl状态
  5. sqlserver2000 mdf 文件导入
  6. mysql 10个日期,MySQL自学篇(10)——日期函数
  7. niceyoo的2020年终总结-2021年Flag
  8. a href点击无效_jquery click()方法模拟点击事件对a标签不生效的解决办法
  9. zappos核心价值_尽管Zappos说了什么,中层管理人员仍然很重要
  10. Python 安装 lxml 插件
  11. 搭建Dubbo开发学习环境——补充新版本的Dubbo-Admin的编译和执行过程
  12. safari java 插件_精通Safari – 如何在 Mac 版 Safari 中使用互联网插件
  13. 新媒体运营胡耀文教程:从运营角度,教你4招破解销售推销套路
  14. 计算机移动硬盘无法访问,移动硬盘无法访问参数不正确的解决方法
  15. 百度2016研发工程师在线编程题
  16. 欧姆龙气压传感器 2SMPB-02E程序编写
  17. vue项目PC端屏幕分辨率与窗口大小自适应
  18. Lenovo系列问题第四期
  19. 小鸭五笔 3.3 版
  20. Python 02 Selenium 账号密码登录CSDN

热门文章

  1. 基于ItemCF算法的电影推荐系统 的代码详解
  2. Part1:Linux基础入门
  3. python画折线图代码实现_用Python画论文折线图、曲线图?几个代码模板轻松搞定!...
  4. 卡波姆对皮肤的作用副作用_玻尿酸对皮肤怎么样?有伤害吗?
  5. 地图成了新的搜索引擎,围绕这个“入口”的竞赛已经展开
  6. Android 实现闹铃效果
  7. 《大数据算法》一1.3 大数据算法设计与分析
  8. 什么是双调排序?(双调归并/双调排序整理)
  9. 兰彻斯特方程Lanchester’s laws仿真python代码
  10. 追猎者:贵金属二次探底未果,本周依然保持逢低做多