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

解析:裸的精确覆盖问题,不过要加优化,不过也是模板。

#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int INF=1e9+;
const int ms=;
const int maxn=ms*ms;
int N,M,ans;
struct DLX
{
int n,id;
int L[maxn],R[maxn],U[maxn],D[maxn];
int C[maxn],S[maxn],loc[maxn][];
void init(int nn=) //传列长
{
n=nn;
for(int i=;i<=n;i++) U[i]=D[i]=i,L[i]=i-,R[i]=i+;
L[]=n; R[n]=;
id=n;
memset(S,,sizeof(S));
}
void AddRow(int x,int col,int A[]) //传入参数是行标号,列长,列数组
{
bool has=false;
int first=id+;
for(int y=;y<=col;y++)
{
if(A[y]==) continue;
has=true;
++id;
L[id]=id-; R[id]=id+;
D[id]=y; U[id]=U[y];
D[U[y]]=id; U[y]=id;
loc[id][]=x,loc[id][]=y;
C[id]=y; S[y]++;
}
if(!has) return;
R[id]=first; L[first]=id;
}
void Remove(int Size)
{
for(int j=D[Size];j!=Size;j=D[j])//将左右两边连接
L[R[j]]=L[j],R[L[j]]=R[j];
}
void Resume(int Size)
{
for(int j=U[Size];j!=Size;j=U[j])//恢复
L[R[j]]=R[L[j]]=j;
}
bool vis[ms];//标记行是否访问过
int h() //启发式函数
{
int ret=;
int i,j,k;
memset(vis,,sizeof(vis));
for(i=R[];i;i=R[i])
{
if(vis[i]) continue;
ret++;
for(j=D[i];j!=i;j=D[j]) //所有关联的标记了
for(k=R[j];k!=j;k=R[k]) vis[C[k]]=;
}
return ret;
}
void dfs(int step)
{
if(step+h()>=ans) return;
if(R[]==){ ans=min(ans,step); return; }
int Min=INF,c=-;
for(int i=R[];i;i=R[i]) if(Min>S[i]){ Min=S[i]; c=i; }
for(int i=D[c];i!=c;i=D[i])
{
Remove(i);
for(int j=R[i];j!=i;j=R[j]) Remove(j);
dfs(step+);
for(int j=L[i];j!=i;j=L[j]) Resume(j);
Resume(i);
}
return;
}
}dlx;
int Mart[ms][ms];
int main()
{
while(scanf("%d%d",&N,&M)!=EOF)
{
dlx.init(N);
ans=;
memset(Mart,,sizeof(Mart));
for(int i=;i<=N;i++) Mart[i][i]=;
while(M--)
{
int x,y;
scanf("%d%d",&x,&y);
Mart[x][y]=Mart[y][x]=;
}
for(int i=;i<=N;i++) dlx.AddRow(i,N,Mart[i]);
dlx.dfs();
printf("%d\n",ans);
}
return ;
}

代码

Hdu3498-whosyourdaddy(精确覆盖模板题)的更多相关文章

  1. hust 1017 dancing links 精确覆盖模板题

    最基础的dancing links的精确覆盖题目 #include <iostream> #include <cstring> #include <cstdio> ...

  2. HUST1017 Exact cover —— Dancing Links 精确覆盖 模板题

    题目链接:https://vjudge.net/problem/HUST-1017 1017 - Exact cover 时间限制:15秒 内存限制:128兆 自定评测 7673 次提交 3898 次 ...

  3. DLX精确覆盖与重复覆盖模板题

    hihoCoder #1317 : 搜索四·跳舞链 原题地址:http://hihocoder.com/problemset/problem/1317 时间限制:10000ms 单点时限:1000ms ...

  4. SPOJ 1771&&DLX精确覆盖,重复覆盖

    DLX的题,做过这题才算是会吧. 这道题转化成了精确覆盖模型来做,一开始,只是单纯的要覆盖完行列和斜线,WA. 后来醒悟了,不能这样,只要覆盖全部行或列即可.虽然如此,但某些细节地方很关键不能考虑到. ...

  5. HUST 1017 - Exact cover (Dancing Links 模板题)

    1017 - Exact cover 时间限制:15秒 内存限制:128兆 自定评测 5584 次提交 2975 次通过 题目描述 There is an N*M matrix with only 0 ...

  6. [DLX精确覆盖] hdu 1603 A Puzzling Problem

    题意: 给你n块碎片,这些碎片不能旋转.翻折. 问你能不能用当中的某些块拼出4*4的正方形. 思路: 精确覆盖裸题了 建图就是看看每一个碎片在4*4中能放哪些位置,这个就作为行. 列就是4*4=16个 ...

  7. POJ 3074 Sudoku DLX精确覆盖

    DLX精确覆盖.....模版题 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8336   Accepted: ...

  8. HDU 3111 Sudoku(精确覆盖)

    数独问题,输入谜题,输出解 既然都把重复覆盖的给写成模板了,就顺便把精确覆盖的模板也写好看点吧...赤裸裸的精确覆盖啊~~~水一水~~~然后继续去搞有点难度的题了... #include <cs ...

  9. ZOJ 3209 Treasure Map 精确覆盖

    题目链接 精确覆盖的模板题, 把每一个格子当成一列就可以. S忘记初始化TLE N次, 哭晕在厕所...... #include<bits/stdc++.h> using namespac ...

随机推荐

  1. Jquery使用tbody编辑功能实现table输入计算功能

    实例:编写一个输入计算(被减数-减数=差). HTML: <body> <table> <thead> <tr> <td >被减数</ ...

  2. Laravel-高级篇-Artisan

    (慕课网_轻松学会Laravel-高级篇_天秤vs永恒老师_http://www.imooc.com/learn/702) 一.概述 Artisan是Laravel中自带的命令行工具的名称 由强大的S ...

  3. 获取sqlserver数据库中所有库、表、字段名的方法

    获取sqlserver数据库中所有库.表.字段名的方法 2009年03月12日 星期四 下午 12:51 1.获取所有数据库名: SELECT Name FROM Master..SysDatabas ...

  4. 三、服务解析(Resolving Services)

    当你完成组件注册,并将组件暴露为适当的服务后你就可以通过容器或者容器的子生命周期域来解析服务(After you have your components registered with approp ...

  5. ul li a active jquery.cookie.js

    div class="righter nav-navicon" id="admin-nav"> <div class="mainer&qu ...

  6. 关于Eclipse中Jsp页面打不开并且显示Failed to create the part's controls的解决办法

    问题描述:同事从svn上导入的一个项目,jdk都设置好了以后,java.xml.html等文件都能打开,唯独jsp文件打不开,并且显示Failed to create the part's contr ...

  7. [翻译] C++ STL容器参考手册 (总册)

    1. 写在最前面 这将是博主的第一篇技术博客,思考再三决定从翻译开始.这将是一个系列的博客,由不同的章节组成,章节之间由超链接联系,开发过程将使用增量式开发,每次完成一个章节.本篇是本系列的总册,提供 ...

  8. Oracle遇到的一些问题

    1.制造数据时出现错误 ORA-30009问题 计划任务: insert into test select rownum,sysdate from dual connect 会出现ORA-30009 ...

  9. freemarker 的replace功能

    替换字符串 replace ${s?replace(‘ba’, ‘XY’ )} ${s?replace(‘ba’, ‘XY’ , ‘规则参数’)}将s里的所有的ba替换成xy 规则参数包含: i r ...

  10. php的一些小笔记-文件函数(1)

    ---恢复内容开始--- 与文件操作相关的函数有一部分可以和linux命令比较,但是我觉得可能还是linux上使用的比较频繁 如:chown,chmod,chgrp,rename,touch,link ...