【DLX算法】hdu3498 whosyourdaddy
题意:给你一个01矩阵,让你选择尽可能少的行数,使得这些行的并集能够覆盖到所有列。
DLX算法求解重复覆盖问题模板,使用估价函数进行剪枝。
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=55+5;
const int maxr=55+5;
const int maxnode=55*55+5;
//ÐбàºÅ´Ó1¿ªÊ¼£¬ÁбàºÅΪ1~n£¬½áµã0ÊDZíÍ·½áµã£»½áµã1~nÊǸ÷Áж¥²¿µÄÐéÄâ½áµã
struct DLX{
int n,sz;//ÁÐÊý£¬½áµã×ÜÊý
int S[maxn];//¸÷ÁнáµãÊý
int row[maxnode],col[maxnode];//¸÷½áµãËùÔÚµÄÐÐÁбàºÅ
int L[maxnode],R[maxnode],U[maxnode],D[maxnode];
int ansd,ans[maxr];//½â
void init(int n){//nÊÇÁÐÊý
this->n=n;
for(int i=0;i<=n;++i){
U[i]=i;
D[i]=i;
L[i]=i-1;
R[i]=i+1;
}
R[n]=0; L[0]=n;
sz=n+1; ansd=1000000007;
memset(S,0,sizeof(S));
}
void addRow(int r,vector<int> columns){
int first=sz;
for(int i=0;i<columns.size();++i){
int c=columns[i];
L[sz]=sz-1;
R[sz]=sz+1;
D[sz]=c;
U[sz]=U[c];
D[U[c]]=sz;
U[c]=sz;
row[sz]=r;
col[sz]=c;
++S[c];
++sz;
}
R[sz-1]=first;
L[first]=sz-1;
}
//˳×ÅÁ´±íA£¬±éÀú³ýsÍâµÄÆäËûÔªËØ
#define FOR(i,A,s) for(int i=A[s];i!=s;i=A[i])
void remove(int c){
L[R[c]]=L[c];
R[L[c]]=R[c];
FOR(i,D,c){
FOR(j,R,i){
U[D[j]]=U[j];
D[U[j]]=D[j];
--S[col[j]];
}
}
}
void restore(int c){
FOR(i,U,c){
FOR(j,L,i){
++S[col[j]];
U[D[j]]=j;
D[U[j]]=j;
}
}
L[R[c]]=c;
R[L[c]]=c;
}
bool dfs(int d){
// printf("%d",d);
if(R[0]==0){//ÕÒµ½½â
ansd=d;//¼Ç¼½âµÄ³¤¶È
return 1;
}
//ÕÒ½áµãÊý×îСµÄÁÐc
int c=R[0];//µÚÒ»¸öδɾ³ýµÄÁÐ
FOR(i,R,0){
if(S[i]<S[c]){
c=i;
}
}
remove(c);//ɾ³ýµÚcÁÐ
FOR(i,D,c){//ÓýáµãiËùÔÚÐи²¸ÇµÚcÁÐ
ans[d]=row[i];
FOR(j,R,i){
remove(col[j]);//ɾ³ý½áµãiËùÔÚÐÐÄܸ²¸ÇµÄËùÓÐÆäËûÁÐ
}
if(dfs(d+1)){
return 1;
}
FOR(j,L,i){
restore(col[j]);//»Ö¸´½áµãiËùÔÚÐÐÄܸ²¸ÇµÄÆäËûËùÓÐÁÐ
}
}
restore(c);//»Ö¸´µÚcÁÐ
return 0;
}
bool solve(vector<int>& v){
v.clear();
if(!dfs(0)){
return 0;
}
for(int i=0;i<ansd;++i){
v.push_back(ans[i]);
}
return 1;
} void remov2(int c){
FOR(i,D,c){
L[R[i]]=L[i];
R[L[i]]=R[i];
}
}
void restor2(int c){
FOR(i,U,c){
L[R[i]]=R[L[i]]=i;
}
}
int f(){//¹À¼Ûº¯Êý
bool vis[maxn];
int res=0;
FOR(i,R,0){
vis[i]=1;
}
FOR(i,R,0){
if(vis[i]){
++res;
vis[i]=0;
FOR(j,D,i){
FOR(k,R,j){
vis[col[k]]=0;
}
}
}
}
return res;
}
void df2(int d){
if(d+f()>=ansd){
return;
}
if(R[0]==0){//ÕÒµ½½â
ansd=min(ansd,d);//¼Ç¼½âµÄ³¤¶È
return;
}
//ÕÒ½áµãÊý×îСµÄÁÐc
int c=R[0];//µÚÒ»¸öδɾ³ýµÄÁÐ
FOR(i,R,0){
if(S[i]<S[c]){
c=i;
}
}
FOR(i,D,c){
remov2(i);
FOR(j,R,i){
remov2(j);
}
df2(d+1);
FOR(j,L,i){
restor2(j);
}
restor2(i);
}
} }dlx;
int n,m;
bool a[60][60];
int main(){
//freopen("hdu3498.in","r",stdin);
int x,y;
while(scanf("%d%d",&n,&m)!=EOF){
dlx.init(n);
memset(a,0,sizeof(a));
for(int i=1;i<=n;++i){
a[i][i]=1;
}
for(int i=1;i<=m;++i){
scanf("%d%d",&x,&y);
a[x][y]=a[y][x]=1;
}
for(int i=1;i<=n;++i){
vector<int> columns;
for(int j=1;j<=n;++j){
if(a[i][j]){
columns.push_back(j);
}
}
if(!columns.empty()){
dlx.addRow(i,columns);
}
}
dlx.df2(0);
printf("%d\n",dlx.ansd);
}
return 0;
}
【DLX算法】hdu3498 whosyourdaddy的更多相关文章
- 关于用舞蹈链DLX算法求解数独的解析
欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 描述 在做DLX算法题中,经常会做到数独类型的题目,那么,如何求解数独类型的题目?其实,学了数独的构建方法,那么DL ...
- 搜索:DLX算法
精确覆盖问题:在一个0-1矩阵中,选定部分行,使得每一列都有且只有一个1.求解一种选法 舞蹈链(Dance Link),也就是一个循环十字链表,可以快速的删掉和恢复某行某列 结合了舞蹈链的搜索就称作D ...
- 【DLX算法】poj2676 Sudoku
DLX算法求解精确覆盖问题模板.赛场上可以参见白书. #include<cstdio> #include<cstring> #include<vector> usi ...
- DLX算法一览
目录: 1 X思想的了解. 链表的递归与回溯. 具体操作. 优化. 一些应用与应用中的再次优化(例题). 练手题 X思想的了解. 首先了解DLX是什么? DLX是一种多元未饱和型指令集结构,DLX 代 ...
- 精确覆盖DLX算法模板另一种写法
代码 struct DLX { int n,id; int L[maxn],R[maxn],U[maxn],D[maxn]; ]; int H[ms]; ) //传列长 { n=nn; ;i<= ...
- 精确覆盖DLX算法模板
代码 struct DLX { int n,id; int L[maxn],R[maxn],U[maxn],D[maxn]; ]; ) //传列长 { n=nn; ;i<=n;i++) U[i] ...
- 舞蹈链(DLX)
舞蹈链(DLX) Tags:搜索 作业部落 评论地址 一.概述 特别特别感谢这位童鞋His blog 舞蹈链是一种优美的搜索,就像下面这样跳舞- 舞蹈链用于解决精确覆盖或者重复覆盖的问题 你可以想象成 ...
- 数独求解 DFS && DLX
题目:Sudoku 题意:求解数独.从样例和结果来看应该是简单难度的数独 思路:DFS 设置3个数组,row[i][j] 判断第i行是否放了j数字,col[i][j] 判断第i列是否放了j数字.squ ...
- POJ2676,HDU4069解决数独的两种实现:DFS、DLX
搜索实现:解决数独有两种思考策略,一种是枚举当前格能填的数字的种数,这里有一优化策略就是先搜索能填入种数小的格子:另一种是考虑处理某一行(列.宫)时,对于某一个没用过的数字,若该行(列.宫)只有一个可 ...
随机推荐
- CentOS7最小化安装连接到网络的解决方案
周末在家想装个虚拟机学一下Hadoop啥的,因为网速小水管比较慢所以下载的是CentOS的minimal版本的: 这个版本安装完之后默认是没有安装net-tools的,也就是说ifconfig不能用: ...
- Ubuntu 下 CodeBlocks 修改用户自定义颜色主题 及 更新CodeBlocks到最新版本
Code::Blocks默认的白色编辑器界面看久了眼睛很累, 所以想换成dark的主题, 眼睛会舒服些. 1. 安装好codeblocks后, 先运行一次, 关闭, 这时程序会提示你是否要保存defa ...
- Linux下的压缩解压缩
Linux下最常用的打包程序就是tar了,使用tar程序打出来的包我们常称为tar包,tar包文件的命令通常都是以.tar结尾的.生成tar包后,就可以用其它的程序来进 行压缩了,所以首先就来讲讲t ...
- 36 - 网络编程-TCP编程
目录 1 概述 2 TCP/IP协议基础 3 TCP编程 3.1 通信流程 3.2 构建服务端 3.3 构建客户端 3.4 常用方法 3.4.1 makefile方法 3.5 socket交互 3.4 ...
- React 16 源码瞎几把解读 【二】 react组件的解析过程
一.一个真正的react组件编译后长啥样? 我们瞎几把解读了react 虚拟dom对象是怎么生成的,生成了一个什么样的解构.一个react组件不光由若干个这些嵌套的虚拟dom对象组成,还包括各种生命周 ...
- FPGA 17最佳论文导读 ESE: Efficient Speech Recognition Engine with Compressed LSTM on FPGA
欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.机器学习技术感兴趣的同学加入. 后面陆续写一些关于神经网络加 ...
- csu 1548(三分)
1548: Design road Time Limit: 2 Sec Memory Limit: 256 MBSubmit: 383 Solved: 200[Submit][Status][We ...
- email的传输协议与格式(资源链接)
以下链接为转载. 传输协议: 发:SMTP 收:POP3, IMAP 格式: MIME
- Ant, JUnit以及Sonar的安装+入门资料
Ant 感觉是个和Make/Grunt类似的东东,build一个项目用的.安装很容易,跟装JDK类似,就是解压->设环境变量->没了.注意装之前要先确认Java装好了(有点废话). 下载地 ...
- Lr中脚本的迭代次数和场景运行时间的关系
Loadrunner中脚本的迭代次数和场景运行时间的关系 LR 的Vugen和controller中迭代是这样的: 当场景的持续时间为“运行至结束”时,以Vugen中设置的迭代次数为准 当场景的持续时 ...