博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 3498 whosyourdaddy
阅读量:6234 次
发布时间:2019-06-22

本文共 4560 字,大约阅读时间需要 15 分钟。

whosyourdaddy

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1028    Accepted Submission(s): 508

Problem Description
sevenzero liked Warcraft very much, but he haven't practiced it for several years after being addicted to algorithms. Now, though he is playing with computer, he nearly losed and only his hero Pit Lord left. sevenzero is angry, he decided to cheat to turn defeat into victory. So he entered "whosyourdaddy", that let Pit Lord kill any hostile unit he damages immediately. As all Warcrafters know, Pit Lord masters a skill called Cleaving Attack and he can damage neighbour units of the unit he attacks. Pit Lord can choice a position to attack to avoid killing partial neighbour units sevenzero don't want to kill. Because sevenzero wants to win as soon as possible, he needs to know the minimum attack times to eliminate all the enemys.
 

 

Input
There are several cases. For each case, first line contains two integer N (2 ≤ N ≤ 55) and M (0 ≤ M ≤ N*N),and N is the number of hostile units. Hostile units are numbered from 1 to N. For the subsequent M lines, each line contains two integers A and B, that means A and B are neighbor. Each unit has no more than 4 neighbor units. The input is terminated by EOF.
 

 

Output
One line shows the minimum attack times for each case.
 

 

Sample Input
5 4
1 2
1 3
2 4
4 5
6 4
1 2
1 3
1 4
4 5
 

 

Sample Output
2
3
 

 

Author
sevenzero
 

 

Source
 

 

Recommend
zhouzeyong
 
 
 
初学请看 :
 
 

这两天学习了Dancing Links  ,它主要对搜索的优化,尤其对于矩阵, 进行深搜的时候,随着层数的加深,矩阵会越来越稀疏,

如果还是用一般的遍历的话, 时间还是没变,还是遍历整个矩阵, 因为矩阵已经变稀疏了,这样做很显然的浪费时间,

这里用到Dancing Links,相信它优美的舞步,一定能打动你的。。

Dancing Links用到一个十字链表, 众所周知 链表对于插入和删除的处理 时间复杂度都是O(1), 这里就要用到链表的这一特性,

对矩阵的某一行或列进行删除的时候 ,先标记,之后把其删除, 等到搜索过后,再把其恢复,时间效率大大的提高。。

Dancing 一般用来解决精确覆盖的问题, 像本题属于 重复覆盖的问题, Dancing Links并不能优化多少,但是这里加一个评估函数,

就在很大的程度上提高了它的效率。、

题目大意:深渊领主有一个技能,溅射(分列攻击),当它把一个单位杀死的时候与该单位 直接 相连的所有单位都要被杀死,

给出n个单位之间的关系,问把这n个单位全部杀死,至少需要攻击多少次。

思路:n个单位排成一排,与该单位相连的单位,以及它自身,位于这一列, 即是Dancing links里面的0-1矩阵。

h函数是这样写的:

当前这种状态至少还需要攻击多少次才能把所有单位消灭。任选没有被标记的一个单位,然后把该列中每一个元素所对应的行,

该行中每一个元素所对应的单位都标记下来。 因为一般我们都只能选取 该列中的一个元素,然后进行处理, 这里把该列中所有的元素都选取出来

,然后进行处理,所需要的次数肯定要比一般情况下的少。。  

 我感觉吧,这个评估函数写的不够风骚,虽然我还没有想到更好的办法。 虽然他能把这题A掉,但是我感觉应该还会有更好的优化!

这道题应该算是一个比较裸的Dancing Links了。

 

1 #include
2 #include
3 #include
4 5 const int N=60; 6 const int V=N*N; 7 8 int L[V],R[V]; //记录左右方向的双向链表 9 int U[V],D[V]; //记录上下方向的双向链表 10 int C[V]; //指向其列指针头的地址 11 int H[N]; //行指针头 12 int S[N]; //记录列链表中节点的总数 13 int size,n,m,ak; 14 int mark[N][N],vis[N]; 15 16 void Link(int r,int c){ 17 S[c]++;C[size]=c; 18 U[size]=U[c]; D[U[c]]=size; 19 D[size]=c; U[c]=size; 20 if(H[r]==-1) 21 H[r]=L[size]=R[size]=size; 22 else{ 23 L[size]=L[H[r]]; R[L[H[r]]]=size; 24 R[size]=H[r]; L[H[r]]=size; 25 } 26 size++; 27 } 28 29 void remove(int Size){ 30 int j; 31 for(j=D[Size];j!=Size;j=D[j]) 32 L[R[j]]=L[j],R[L[j]]=R[j]; 33 } 34 35 void resume(int Size){ 36 int j; 37 for(j=D[Size];j!=Size;j=D[j]) 38 L[R[j]]=R[L[j]]=j; 39 } 40 41 int h(){ 42 int count=0; 43 int i,j,k; 44 memset(vis,0,sizeof(vis)); 45 for(i=R[0];i;i=R[i]){ 46 if(vis[i]) 47 continue; 48 count++; 49 for(j=D[i];j!=i;j=D[j]) 50 for(k=R[j];k!=j;k=R[k]) 51 vis[C[k]]=1; 52 } 53 return count; 54 } 55 56 void Dance(int k){ 57 if(k+h()>=ak) 58 return ; 59 if(!R[0]){ 60 if(k
S[i]) 68 min=S[i],c=i; 69 for(i=D[c];i!=c;i=D[i]){ 70 remove(i); 71 for(j=R[i];j!=i;j=R[j]) 72 remove(j); 73 Dance(k+1); 74 for(j=R[i];j!=i;j=R[j]) 75 resume(j); 76 resume(i); 77 } 78 } 79 80 int main(){ 81 82 //freopen("input.txt","r",stdin); 83 84 while(~scanf("%d%d",&n,&m)){ 85 int i,j; 86 for(i=0;i<=n;i++){ 87 S[i]=0; 88 U[i]=D[i]=i; 89 L[i+1]=i;R[i]=i+1; 90 } 91 R[n]=0; 92 size=n+1; 93 memset(mark,0,sizeof(mark)); 94 memset(H,-1,sizeof(H)); 95 int a,b; 96 while(m--){ 97 scanf("%d%d",&a,&b); 98 mark[a][b]=mark[b][a]=1; 99 }100 for(i=1;i<=n;i++)101 for(j=1;j<=n;j++)102 if(mark[i][j] || i==j)103 Link(i,j);104 ak=N;105 Dance(0);106 printf("%d\n",ak);107 }108 return 0;109 }

 

转载地址:http://zxqna.baihongyu.com/

你可能感兴趣的文章
nagios客户端未启动报错
查看>>
南京大学周志华教授当选欧洲科学院外籍院士
查看>>
《OpenGL ES应用开发实践指南:Android卷》—— 1.3 初始化OpenGL
查看>>
马士兵教学语录
查看>>
计算机网络与Internet应用
查看>>
MongodDB学习笔记(二)(复制)
查看>>
oracle在线迁移同步数据,数据库报错
查看>>
linux性能剖析工具
查看>>
VS2005环境下采用makefile编译、使用libjpeg.lib函数库
查看>>
EBS多语言
查看>>
说说设计模式~ 模版模式(Template)
查看>>
【linux】文件隐藏属性
查看>>
Java 命名规则
查看>>
RTC设备驱动
查看>>
小公司的管理
查看>>
无废话WCF入门教程三[WCF的宿主]
查看>>
iOS手势识别的详细使用(拖动,缩放,旋转,点击,手势依赖,自定义手势)
查看>>
详细解析:如何制作嵌入式Linux文件系统
查看>>
C# 两个独立exe程序直接通信
查看>>
【Unity3d】【项目学习心得】从资源server下载资源(一)
查看>>