DLX模板
对于数独问题
const int N=; //3*3数独
const int MaxN=N*N*N+; // 一格能填9个数 9*9格
const int MaxM=N*N*+; // 9*9*4=(9+9+9)*9+9*9 (9+9+9)是9行 9列 9格 *9是9个数 9*9是81个格子
const int maxnode=MaxN*+MaxM+;
char g[MaxN];
struct DLX
{
int n, m, size;
int U[maxnode], D[maxnode], R[maxnode], L[maxnode], Row[maxnode], Col[maxnode];
int H[MaxN], S[MaxM]; // S: 各列节点数
int ansd, ans[MaxN];
void init(int _n, int _m)
{
n=_n;
m=_m;
for(int i=; i<=m; i++)
{
S[i]=; //每一列元素个数
U[i]=D[i]=i;//上下指针
L[i]=i-; //←
R[i]=i+; //→
}
R[m]=; //循环 最后一个指向第一个
L[]=m; //第一个往前指向最后一个
size=m; // 节点总数
for(int i=; i<=n; i++)
H[i]=-; //头指针
}
void Link(int r, int c)
{
S[Col[++size]=c]++;
Row[size]=r;
D[size]=D[c];
U[D[c]]=size;
U[size]=c;
D[c]=size;
if(H[r]<)
H[r]=L[size]=R[size]=size;
else
{
R[size]=R[H[r]];
L[R[H[r]]]=size;
L[size]=H[r];
R[H[r]]=size;
}
}
void remove(int c)
{
L[R[c]]=L[c];
R[L[c]]=R[c];
for(int i=D[c]; i!=c; i=D[i])
for(int j=R[i]; j!=i; j=R[j])
{
U[D[j]]=U[j];
D[U[j]]=D[j];
S[Col[j]]--;
}
}
void resume(int c)
{
for(int i=U[c]; i!=c; i=U[i])
for(int j=L[i]; j!=i; j=L[j])
S[Col[U[D[j]]=D[U[j]]=j]]++;
L[R[c]]=R[L[c]]=c;
}
bool Dance(int d)
{
if(R[]==)
{
for(int i=;i<d;i++)
g[(ans[i]-)/N]=(ans[i]-)%N+'A';
for(int i=;i<N;i++)
{
for(int j=;j<N;j++)
printf("%c", g[i*N+j]);
printf("\n");
}
printf("\n");
return true;
}
int c=R[];
for(int i=R[]; i!=; i=R[i])
if(S[i]<S[c])
c=i;
remove(c);
for(int i=D[c]; i!=c; i=D[i])
{
ans[d]=Row[i];
for(int j=R[i]; j!=i; j=R[j])
remove(Col[j]);
if(Dance(d+))
return true;
for(int j=L[i]; j!=i; j=L[j])
resume(Col[j]);
}
resume(c);
return false;
}
} dlx; void palce(int &r, int &c1, int &c2, int &c3, int &c4, int i, int j, int k)
{
r=(i*N+j)*N+k; // 第几行
c1=i*N+j+; // 第几个格子
c2=N*N+i*N+k; // 第i行上的k
c3=N*N*+j*N+k; // 第j列上的k
c4=N*N*+((i/)*+(j/))*N+k; // 某宫中的k;
}
char s[];
int main()
{
while(~scanf("%s", g))
{
for(int i=;i<;i++)
{
scanf("%s", s);
memcpy(g+*i, s, );
}
dlx.init(N*N*N, *N*N);
for(int i=; i<N; i++)
for(int j=; j<N; j++)
for(int k=; k<=; k++)
if(g[i*N+j]=='-' || g[i*N+j]==k+'A'-)
{
int r, c1, c2, c3, c4;
palce(r, c1, c2, c3, c4, i, j, k);
dlx.Link(r, c1);
dlx.Link(r, c2);
dlx.Link(r, c3);
dlx.Link(r, c4);
}
dlx.Dance();
}
return ;
}
POJ 3076
( 以上的模板只能做唯一解的数独)
判读多解要做dfs
对于可重复覆盖
#ifdef _WIN32
#define LLD "%I64d"
#else
#define LLD "%lld"
#endif
#pragma comment(linker, "/STACK:1024000000,1024000000")
//LL quick(LL a, LL b){LL ans=1;while(b){if(b & 1)ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans%mod;}
inline int read(){char ch=' ';int ans=;while(ch<'' || ch>'')ch=getchar();while(ch<='' && ch>=''){ans=ans*+ch-'';ch=getchar();}return ans;}
inline void print(LL x){printf(LLD, x);puts("");}
//inline void read(LL &ret){char c;int sgn;LL bit=0.1;if(c=getchar(),c==EOF) return ;while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();sgn=(c=='-')?-1:1;ret=(c=='-')?0:(c-'0');while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');if(c==' '||c=='\n'){ ret*=sgn; return ; }while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;ret*=sgn;} const int maxnode=;
const int MaxN=;
const int MaxM=;
int K;
struct DLX
{
int n, m, size;
int U[maxnode], D[maxnode], R[maxnode], L[maxnode], Row[maxnode], Col[maxnode];
int H[MaxN], S[MaxM]; // S: 各列节点数
int ans[MaxN];
void init(int _n, int _m)
{
n=_n;
m=_m;
for(int i=; i<=m; i++)
{
S[i]=; //每一列元素个数
U[i]=D[i]=i;//上下指针
L[i]=i-; //←
R[i]=i+; //→
}
R[m]=; //循环 最后一个指向第一个
L[]=m; //第一个往前指向最后一个
size=m; // 节点总数
for(int i=; i<=n; i++)
H[i]=-; //头指针
}
void Link(int r, int c)
{
S[Col[++size]=c]++;
Row[size]=r;
D[size]=D[c];
U[D[c]]=size;
U[size]=c;
D[c]=size;
if(H[r]<)
H[r]=L[size]=R[size]=size;
else
{
R[size]=R[H[r]];
L[R[H[r]]]=size;
L[size]=H[r];
R[H[r]]=size;
}
}
void remove(int c)
{
for(int i=D[c]; i!=c; i=D[i])
L[R[i]]=L[i], R[L[i]]=R[i];
}
void resume(int c)
{
for(int i=U[c]; i!=c; i=U[i])
L[R[i]]=R[L[i]]=i;
}
bool v[maxnode];
int f()
{
int ret=;
for(int c=R[];c!=;c=R[c])
v[c]=;
for(int c=R[];c!=;c=R[c])
if(v[c])
{
ret++;
v[c]=;
for(int i=D[c];i!=c;i=D[i])
for(int j=R[i];j!=i;j=R[j])
v[Col[j]]=;
}
return ret;
}
bool Dance(int d)
{
if(d+f()>K)
return false;
if(R[]==)
return d<=K;
int c=R[];
for(int i=R[]; i!=; i=R[i])
if(S[i]<S[c])
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);
if(Dance(d+))
return true;
for(int j=L[i]; j!=i; j=L[j])
resume(j);
resume(i);
}
return false;
}
} dlx;
struct node
{
int x, y;
}city[MaxM];
LL dis(node a, node b)
{
return (LL)abs(a.x-b.x)+(LL)abs(a.y-b.y);
}
int main()
{
int t, ca=;
t=read();
while(t--)
{
int n=read();
K=read();
for(int i=;i<n;i++)
scanf("%d%d", &city[i].x, &city[i].y);
LL l=, r=100000000000LL, ans=;
while(l<=r)
{
LL mid=(l+r)>>;
dlx.init(n, n);
for(int i=;i<n;i++)
for(int j=;j<n;j++)
if(dis(city[i], city[j])<=mid)
dlx.Link(i+, j+);
if(dlx.Dance())
{
r=mid-;
ans=mid;
}
else
l=mid+;
}
printf("Case #%d: ", ca++);
print(ans);
}
return ;
}
HDUOJ 5046
两篇资料:
http://wenku.baidu.com/view/b3f6fa868762caaedd33d47a.html
http://wenku.baidu.com/view/4ab7bd00a6c30c2259019eae.html?from=rec&pos=0&weight=31&lastweight=5&count=5
DLX模板的更多相关文章
- poj 3740 Easy Finding 二进制压缩枚举dfs 与 DLX模板详细解析
题目链接:http://poj.org/problem?id=3740 题意: 是否从0,1矩阵中选出若干行,使得新的矩阵每一列有且仅有一个1? 原矩阵N*M $ 1<= N <= 16 ...
- hdu 5046 二分+DLX模板
http://acm.hdu.edu.cn/showproblem.php?pid=5046 n城市建k机场使得,是每个城市最近机场的距离的最大值最小化 二分+DLX 模板题 #include < ...
- [ACM] POJ 3740 Easy Finding (DLX模板题)
Easy Finding Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16178 Accepted: 4343 Des ...
- [ACM] HUST 1017 Exact cover (Dancing Links,DLX模板题)
DESCRIPTION There is an N*M matrix with only 0s and 1s, (1 <= N,M <= 1000). An exact cover is ...
- UVALive 2659 数独 DLX模板
建图: 从1到16枚举所有的行.列上放的数. 代码: #include <iostream> #include <cstdio> #include <cstring> ...
- 舞蹈链 DLX
欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 舞蹈链是一个非常玄学的东西…… 问题模型 精确覆盖问题:在一个01矩阵中,是否可以选出一些行的集合,使得在这些行的集 ...
- 【UVA1309】Sudoku(DLX)
点此看题面 大致题意: 让你填完整一个\(16*16\)的数独. 解题思路 我们知道,数独问题显然可以用\(DLX\)解决. 考虑对于一个数独,它要满足的要求为:每个位置都必须有数,每一行都必须有全部 ...
- HDU 3957 Street Fighter (最小支配集 DLX 重复覆盖+精确覆盖 )
DLX经典题型,被虐惨了…… 建一个2*N行3*N列的矩阵,行代表选择,列代表约束.前2*N列代表每个人的哪种状态,后N列保证每个人至多选一次. 显然对手可以被战胜多次(重复覆盖),每个角色至多选择一 ...
- Dancing Links and Exact Cover
1. Exact Cover Problem DLX是用来解决精确覆盖问题行之有效的算法. 在讲解DLX之前,我们先了解一下什么是精确覆盖问题(Exact Cover Problem)? 1.1 Po ...
随机推荐
- scala学习笔记:理解stream和view
先来个正常的: scala> (0 to 5).map((x:Int)=>{println(x);x*2}).foreach(println) 0 1 2 3 4 5 0 2 4 6 8 ...
- 快速开启Windows 的各种任务及 bat(ch)脚本
MSC It is the Microsoft Management Console Snap-in Control File, like services.msc, devmgmt.msc (Dev ...
- forever start Error: Cannot find module './daemon.v0.10.26'
我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3590158.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...
- C#与C++相比较之STL篇(续一)
本篇接<C#与C++相比较之STL篇>,主要探索C++STL的两个组件:算法和仿函数,以及C#的linq和拉姆达表达式.委托. STL的算法与仿函数 算法是个庞大的主题,STL包含了超过1 ...
- 回溯算法之n皇后问题
今天在看深度优先算法的时候,联想到DFS本质不就是一个递归回溯算法问题,只不过它是应用在图论上的.OK,写下这篇博文也是为了回顾一下回溯算法设计吧. 学习回溯算法问题,最为经典的问题我想应该就是八皇后 ...
- ios中XPath的语法
在XML的读写中,我们知道有Xpath的语法 1.定位节点:(/)代表绝对的路径,代表起始地位置.(//)表示文件中所有符合模式的元素都会被选出来,即使是处于树中不同的层级也会被选出来 2.KissX ...
- sql 修改字段小记
增加字段默认值: alter table 表名 ADD 字段 类型 NULL Default 0 修改字段类型: alter table 表名 alter column UnitPrice decim ...
- C#之Attribute(特性)
本文主要复习下基础知识: 1.C#系统自带的特性: 建立一个控制台项目取名为AttributeTest: 我们添加了一个系统自带的Attribute叫Condition,这个特性表示在程序的DEBUG ...
- 泛型转Datatable
//自定义扩展方法 public static class ExtMethod { //泛型转为DataTable public static DataTable AsDataTable<T&g ...
- 【BZOJ】1013: [JSOI2008]球形空间产生器sphere
[BZOJ]1013: [JSOI2008]球形空间产生器sphere 题意:给n+1个n维的点的坐标,要你求出一个到这n+1个点距离相等的点的坐标: 思路:高斯消元即第i个点和第i+1个点处理出一个 ...