题目:

http://acm.hdu.edu.cn/showproblem.php?pid=3498

题意:

有 n n个敌人,其中有mm对敌人互为邻居,当你攻击杀死一个敌人时,同时会杀死它所有的邻居,问最少需要多少次攻击才能杀死所有敌人

思路:

DLX DLX重复覆盖,题很裸,很容易建图,对于第 i i个敌人,如果它和jj互为邻居,则有 matrix[i][j]=matrix[j][i]=1 matrix[i][j] = matrix[j][i] = 1,否则为 0 0,然后跑一下重复覆盖求最少次数即可。对比精确覆盖和重复覆盖,二者有些不同,精确覆盖选定一列后,删除此列以及能覆盖此列的行,然后枚举选取某行作为解集一部分的时候,要把覆盖此行的所有列以及覆盖这些列的行删除(读起来有点拗口),因为这些行和当前选取的行已经冲突了,这样保证最终答案每列只被覆盖11次,对于重复覆盖,选定一列后,只删除当前列,然后枚举某行作为解集一部分的时候,只删除覆盖此行的所有列,因为不需要保证每列仅被覆盖 1 <script type="math/tex" id="MathJax-Element-1152">1</script>次。两者模板稍有不同。
另外重复覆盖每次删除的行变少了,意味着速度变慢了,因此需要强剪枝,用一个估价函数计算在当前状况下至少还需要多少次才能完全覆盖,加上已用的次数,和答案对比,大于等于答案就可以剪枝了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>using namespace std;const int X = 10000 + 10, N = 100 + 10, M = 100 + 10, INF = 0x3f3f3f3f;bool g[N][M];
int ans;struct DLX
{int U[X], D[X], L[X], R[X], row[X], col[X];int H[N], S[M];int head, sz, tot, n, m;bool vis[M];void init(int _n, int _m){n = _n, m = _m;for(int i = 0; i <= m; i++)L[i] = i-1, R[i] = i+1, U[i] = D[i] = i, S[i] = 0;head = 0, tot = 0, sz = m;L[head] = m, R[m] = head;for(int i = 1; i <= n; i++) H[i] = -1;}void link(int r, int c){++S[col[++sz]=c];row[sz] = r;D[sz] = D[c], U[D[c]] = sz;U[sz] = c, D[c] = sz;if(H[r] < 0) H[r] = L[sz] = R[sz] = sz;else R[sz] = R[H[r]], L[R[H[r]]] = sz, L[sz] = H[r], R[H[r]] = sz;}void del(int x)//这里的x是点编号,精确覆盖中这里是列号{for(int i = D[x]; i != x; i = D[i])R[L[i]] = R[i], L[R[i]] = L[i];}void recover(int x)//同上{for(int i = U[x]; i != x; i = U[i])R[L[i]] = L[R[i]] = i;}int fun_f() //估价函数,估计当前情况下最少还需要多少次才能完成覆盖,只是估计值,只会比真实次数少,从代码中可以明显看出{memset(vis, 0, sizeof vis);int num = 0;for(int i = R[head]; i != head; i = R[i])if(! vis[i]){vis[i] = true;num++;for(int j = D[i]; j != i; j = D[j])for(int k = R[j]; k != j; k = R[k])vis[col[k]] = true;}return num;}void  dance(int dep){if(R[head] == head){ans = min(ans, dep-1); return;}if(dep-1 + fun_f() >= ans) return ;//剪枝int c = R[head];for(int i = R[head]; i != head; i = R[i])if(S[i] < S[c]) c = i;for(int i = D[c]; i != c; i = D[i]){del(i);for(int j = R[i]; j != i; j = R[j]) del(j);dance(dep + 1);for(int j = L[i]; j != i; j = L[j]) recover(j);recover(i);}}
}dlx;
int main()
{int n, m;while(~ scanf("%d%d", &n, &m)){memset(g, 0, sizeof g);int a, b;for(int i = 1; i <= m; i++){scanf("%d%d", &a, &b);g[a][b] = g[b][a] = true;}dlx.init(n, n);for(int i = 1; i <= n; i++) g[i][i] = true;for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++)if(g[i][j]) dlx.link(i, j);ans = INF;dlx.dance(1);printf("%d\n", ans);}return 0;
}

HDU 3498 whosyourdaddy DLX重复覆盖相关推荐

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

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

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

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

  3. HDU 3498 whosyourdaddy (可重复覆盖舞蹈链)

    题意: 给出N个点,M个边构成图.每选取一个点都可以覆盖其相邻点,问要覆盖所有点最少选几个点 思路: 每个点都作为一个点集,进行爆搜覆盖,舞蹈链模板题. 代码: #include <bits/s ...

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

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

  5. hdu - 3498 - whosyourdaddy(反复覆盖DLX)

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

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

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

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

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

  8. hdu 3498 whosyourdaddy

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

  9. hdu 3498 whosyourdaddy (重复覆盖,DLX+迭代加深A*)

    题意:有一个英雄,他有一个技能,可以使一个点和与他相邻的点受到伤害,问最少攻击几个点可以使所有点至少被伤害一次. 思路:DLX.很裸.设行为每一个点,列为攻击点,在这里行元素与列元素都为n.然后DLX ...

最新文章

  1. HTTP中request请求参数的设置
  2. 1101 Quick Sort (25 分)【难度: 一般 / 知识点: 快排】
  3. 科大星云诗社动态20210313
  4. 网易游戏2011.10.15校园招聘会笔试题
  5. Boost:双图bimap与Boost类型的测试程序
  6. 大脑芯片首次进行人类测试 增强记忆指日可待?
  7. 【DevCloud·敏捷智库】如何利用故事点做估算
  8. 深度学习经典算法 | 遗传算法详解
  9. 【节能学院】油烟浓度在线监测仪在浙江省某市餐饮油烟监测治理项目中的应用
  10. vue 会将连续空格自动合并成一个空格(避免空格合并)
  11. Quality Trimming Via Trimmomatic
  12. 萌新,C++、Java、Python 选择哪个好?
  13. 01-前端工程化概述
  14. 美团智能配送系统的运筹优化实战-笔记
  15. 用c语言按键控制数码管,按键与数码管C语言例程
  16. 三、项目进度管理(输入/工具与技术/输出)
  17. 键鼠共享工具Barrier
  18. 一步两步带你实现Android沉浸式设计
  19. golang微服务框架go-zero系列-1:适合创业的golang微服务框架go-zero + 金光灿灿的gorm V2实践
  20. unittest用法

热门文章

  1. dayz哪些服务器物品是互通,DayZ服务器常用的一些武器食物吃喝子弹弹夹配件背包代码...
  2. Python 实现彩票机选原理——从此再也不用纠结彩票选号
  3. stm32开发板下esp8266通信
  4. LatinIME默认打开各国语言
  5. Visual Studio创建自己的代码片段
  6. 第22章 OTP介绍
  7. springBoot+actuator 实现优雅的停止服务器
  8. 计算机网络原理(21)——信道与信道容量、基带传输、频带传输、物理层接口
  9. EMule搜书技巧(经典原创!)
  10. C - Coolest Ski Route关于最长路的一些问题(未完)