hdu 3498 whosyourdaddy
Dancing Links 重复覆盖问题~
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3498
这两天学习了Dancing Links ,它主要对搜索的优化,尤其对于矩阵, 进行深搜的时候,随着层数的加深,矩阵会越来越稀疏,
如果还是用一般的遍历的话, 时间还是没变,还是遍历整个矩阵, 因为矩阵已经变稀疏了,这样做很显然的浪费时间,
这里用到Dancing Links,相信它优美的舞步,一定能打动你的。。
Dancing Links用到一个十字链表, 众所周知 链表对于插入和删除的处理 时间复杂度都是O(1), 这里就要用到链表的这一特性,
对矩阵的某一行或列进行删除的时候 ,先标记,之后把其删除, 等到搜索过后,再把其恢复,时间效率大大的提高。。
Dancing 一般用来解决精确覆盖的问题, 像本题属于 重复覆盖的问题, Dancing Links并不能优化多少,但是这里加一个评估函数,
就在很大的程度上提高了它的效率。、
题目大意:深渊领主有一个技能,溅射(分列攻击),当它把一个单位杀死的时候与该单位 直接 相连的所有单位都要被杀死,
给出n个单位之间的关系,问把这n个单位全部杀死,至少需要攻击多少次。
思路:n个单位排成一排,与该单位相连的单位,以及它自身,位于这一列, 即是Dancing links里面的0-1矩阵。
h函数是这样写的:
当前这种状态至少还需要攻击多少次才能把所有单位消灭。任选没有被标记的一个单位,然后把该列中每一个元素所对应的行,
该行中每一个元素所对应的单位都标记下来。 因为一般我们都只能选取 该列中的一个元素,然后进行处理, 这里把该列中所有的元素都选取出来
,然后进行处理,所需要的次数肯定要比一般情况下的少。。
我感觉吧,这个评估函数写的不够风骚,虽然我还没有想到更好的办法。 虽然他能把这题A掉,但是我感觉应该还会有更好的优化!
这道题应该算是一个比较裸的Dancing Links了。。
code:
![](/assets/blank.gif)
![](/assets/blank.gif)
1 # include<stdio.h> 2 # include<string.h> 3 # define N 60 4 # define V N*N 5 int L[V],R[V];//记录左右方向的双向链表
6 int U[V],D[V];//记录上下方向的双向链表 7 int C[V];//指向其列指针头的地址 8 int H[N];//行指针头 9 int S[N];//记录列链表中节点的总数 10 int size,n,m,ak; 11 int mark[N][N],visit[N]; 12 void Link(int r,int c) 13 { 14 S[c]++;C[size]=c; 15 U[size]=U[c];D[U[c]]=size; 16 D[size]=c;U[c]=size; 17 if(H[r]==-1) H[r]=L[size]=R[size]=size; 18 else 19 { 20 L[size]=L[H[r]];R[L[H[r]]]=size; 21 R[size]=H[r];L[H[r]]=size; 22 } 23 size++; 24 } 25 void remove(int Size) 26 { 27 int j; 28 for(j=D[Size];j!=Size;j=D[j]) 29 L[R[j]]=L[j],R[L[j]]=R[j]; 30 } 31 void resume(int Size) 32 { 33 int j; 34 for(j=D[Size];j!=Size;j=D[j]) 35 L[R[j]]=R[L[j]]=j; 36 } 37 int h() 38 { 39 int count=0,i,j,k; 40 memset(visit,0,sizeof(visit)); 41 for(i=R[0];i;i=R[i]) 42 { 43 if(visit[i]) continue; 44 count++; 45 for(j=D[i];j!=i;j=D[j]) 46 { 47 for(k=R[j];k!=j;k=R[k]) 48 visit[C[k]]=1; 49 } 50 } 51 return count; 52 } 53 void Dance(int k) 54 { 55 int i,j,min,c; 56 if(k+h()>=ak) return; 57 if(!R[0]) 58 { 59 if(k<ak) ak=k; 60 return; 61 } 62 for(min=N,i=R[0];i;i=R[i]) 63 if(min>S[i]) min=S[i],c=i; 64 for(i=D[c];i!=c;i=D[i]) 65 { 66 remove(i); 67 for(j=R[i];j!=i;j=R[j]) 68 remove(j); 69 Dance(k+1); 70 for(j=R[i];j!=i;j=R[j]) 71 resume(j); 72 resume(i); 73 } 74 } 75 int main() 76 { 77 int i,j,a,b; 78 while(scanf("%d%d",&n,&m)!=EOF) 79 { 80 for(i=0;i<=n;i++) 81 { 82 S[i]=0; 83 U[i]=D[i]=i; 84 L[i+1]=i;R[i]=i+1; 85 }R[n]=0; 86 size=n+1; 87 memset(mark,0,sizeof(mark)); 88 memset(H,-1,sizeof(H)); 89 while(m--) 90 { 91 scanf("%d%d",&a,&b); 92 mark[a][b]=mark[b][a]=1; 93 } 94 for(i=1;i<=n;i++) 95 { 96 for(j=1;j<=n;j++) 97 { 98 if(mark[i][j] || i==j) Link(i,j); 99 }100 }101 ak=N;102 Dance(0);103 printf("%d\n",ak);104 }105 return 0;106 }
转载于:https://www.cnblogs.com/183zyz/archive/2011/08/07/2129801.html
hdu 3498 whosyourdaddy相关推荐
- hdu - 3498 - whosyourdaddy(重复覆盖DLX)
题意:N(2 ≤ N ≤ 55)个点,M(0 ≤ M ≤ N*N)条无向边,删除一个点会把与其相邻的点一起删掉,问最少删几次可以删掉所有点. 题目链接:http://acm.hdu.edu.cn/sh ...
- HDU 3498 whosyourdaddy DLX重复覆盖
题目: http://acm.hdu.edu.cn/showproblem.php?pid=3498 题意: 有 n n个敌人,其中有mm对敌人互为邻居,当你攻击杀死一个敌人时,同时会杀死它所有的邻居 ...
- HDU 3498 whosyourdaddy(DLX重复覆盖)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3498 n个点,m条无向边,删除一个点会把与其相邻的点一起删掉,问最少删几次可以删掉所有 ...
- hdu - 3498 - whosyourdaddy(反复覆盖DLX)
题意:N(2 ≤ N ≤ 55)个点,M(0 ≤ M ≤ N*N)条无向边,删除一个点会把与其相邻的点一起删掉.问最少删几次能够删掉全部点. 题目链接:http://acm.hdu.edu.cn/sh ...
- HDU 3498 whosyourdaddy (可重复覆盖舞蹈链)
题意: 给出N个点,M个边构成图.每选取一个点都可以覆盖其相邻点,问要覆盖所有点最少选几个点 思路: 每个点都作为一个点集,进行爆搜覆盖,舞蹈链模板题. 代码: #include <bits/s ...
- HDU 3498 whosyourdaddy(Dancing_Links重复覆盖)
题目地址 题意:给你n个城市,m条道路,每次摧毁一个城市会附带把与它直接连接的城市的摧毁,一个城市可以重复摧毁(如果不能重复就是精确覆盖了),问你最少摧毁多少个城市能把所有城市摧毁. 思路:我们可以构 ...
- hdu 3498 whosyourdaddy 重复覆盖
#include <bits/stdc++.h> using namespace std; struct DLX {const static int maxn=64,maxm=64,max ...
- hdu 3498 whosyourdaddy (重复覆盖,DLX+迭代加深A*)
题意:有一个英雄,他有一个技能,可以使一个点和与他相邻的点受到伤害,问最少攻击几个点可以使所有点至少被伤害一次. 思路:DLX.很裸.设行为每一个点,列为攻击点,在这里行元素与列元素都为n.然后DLX ...
- [DLX重复覆盖] hdu 3498 whosyourdaddy
题意: 给N个怪,M个关系. 每个关系代表a和b是邻居. 然后问每次攻击你可以攻击一个怪以及它的全部邻居 问最少需要几次攻击能把怪全部杀死. 思路: 怪为行和列,然后对面每个怪的邻居都是这个怪的列建图 ...
最新文章
- Linux大神必会操作——系统排错
- 原生 js 上传图片
- 满园尽是503,记曾经的一次IIS 7性能考验
- pytorch训练过程中loss出现NaN的原因及可采取的方法
- python手机版iphone-Python编程神器
- 两个条件一个为false就运行_Python入门基础实例讲解——两个数字比大小,并输出最大值...
- 蓝桥杯历届试题 国王的烦恼(并查集逆序加边+坑)
- mysql----innodb统计信息
- java swarm集群_52个Java程序员不可或缺的 Docker 工具
- 东京奥运出租车超预算想找滴滴接盘被拒 网友:真当人傻吗?
- php论坛权限设置,php – 如何实现论坛权限
- python数据导出excel_【python Excel】如何使用python将大量数据导出到Excel中的小技巧之一...
- PHP问题 —— The use statement with non-compound name
- H264的RTP负载打包的数据包格式,分组,分片
- 结构体定义 typedef struct LNode 用法说明
- vivo是安卓手机吗_拜托你看看vivo手机自带的翻译功能,这么强大的功能浪费了合适吗...
- vs2015智能提示英文改为中文
- OneTab插件的替代产品-OneTab Pro
- nginx端口映射配置(Windows)
- 易语言子程序和C语言子程序,一步一步跟我学易语言之认识窗口组件和子程序...
热门文章
- LP、HPM、HPC、HPC等工艺制作博文
- 江苏省工业互联网标识创新应用案例集
- Python-scrapy爬取起点榜单信息
- Shell之$(cd $(dirname $0); pwd)命令详解
- Spring boot mybatis 打印SQL语句
- 【面经】高德地图 C++ 研发 一面
- 网络阶段测试理论摘要
- 水星mac1300r虚拟服务器,水星(MERCURY)MAC1300R无线路由器怎么设置? | 192路由网
- RecyclerView详细用法
- Linux 刻录CD/DVD命令 growisofs/mkisofs/cdrecord