洛谷 P4929 【模板】舞蹈链(DLX)
作者:互联网
DLX例题(洛谷模板题就是省选难度了qwq)。
DLX的具体思想我就不赘述了,网上有很多讲的不错的。下附链接
AC代码如下(代码思路就看注释吧……)
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<algorithm> #define mx 250505 using namespace std; int n,m,cnt; int l[mx],r[mx],u[mx],d[mx],row[mx],col[mx];//定义一个点的左右上下以及行数列数。 int h[mx],s[mx];//一行的第一个数 ,一列有几个数 int ansk[mx];//答案 inline void Init(int m){//初始化m列。m+1个数,0为head(无实际意义,是最后用来判断的 for(int i=0;i<=m;i++){ r[i]=i+1; l[i]=i-1; u[i]=d[i]=i; } r[m]=0,l[0]=m; memset(h,-1,sizeof(h)); memset(s,0,sizeof(s)); cnt=m+1;//之后录入的数从m+1的下标开始 } inline void link(int R,int C){//插入一个在R行C列的点 s[C]++; row[cnt]=R,col[cnt]=C;//记录行和列 u[cnt]=C;//cnt的上面为c,即1~m d[cnt]=d[C];//cnt的下面是原先C的下面 u[d[C]]=cnt;//原先c的下面的上面是cnt d[C]=cnt; //c的下面是cnt。一系列操作即将cnt插入C和C下面一个数之间,让cnt成为最接近c的那个数(这样写的话最终其实u是在下面的意思的感觉…… if(h[R]==-1)//如果这一行没有数的话就将该数作为第一个数录入 h[R]=r[cnt]=l[cnt]=cnt; else{//有数的话 r[cnt]=h[R];//将cnt的右边连接到h[R]的左边 l[cnt]=l[h[R]];//将cnt的左边连接到h[R]的左边 r[l[h[R]]]=cnt;//将原来h[R]的左边连接到cnt的左边 l[h[R]]=cnt;//将cnt连接到h[R]的左边(感觉这样写也是左右颠倒的感觉……不过倒是不影响 } cnt++; return; } inline void remove(int C){//删除c列 r[l[C]]=r[C],l[r[C]]=l[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]]--;//该数所在列内数量-1 } return; } inline void resume(int C){ r[l[C]]=C,l[r[C]]=C; for(int i=d[C];i!=C;i=d[i]) for(int j=r[i];j!=i;j=r[j]){ u[d[j]]=j; d[u[j]]=j; s[col[j]]++; } return; } bool dance(int deep){ if(r[0]==0){//如果列删光了且除了head没有元素留下来。则表示该情况成立 for(int i=0;i<deep;i++) printf("%d ",ansk[i]); return 1; } int c=r[0]; for(int i=r[0];i!=0;i=r[i])//优先从列中数最少的开始找。缩小查找范围 if(s[i]<s[c]) c=i; remove(c);//删除c列 for(int i=d[c];i!=c;i=d[i]){//从c列当中选1行进行查找 ansk[deep]=row[i];//记录当前被删的行数 for(int j=r[i];j!=i;j=r[j]) //加上这句话后感觉remove函数中的第三个循环没什么必要的样子…… remove(col[j]); if(dance(deep+1)) return 1; for(int j=l[i];j!=i;j=l[j]) resume(col[j]); } resume(c); return 0; } int main(){ scanf("%d%d",&n,&m); Init(m); char temp; int k; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ scanf("%d",&k); if(k) link(i,j); } if(!dance(0)) printf("No Solution!"); return 0; }
标签:P4929,洛谷,DLX,int,网站,include,mx 来源: https://www.cnblogs.com/mikku39/p/14453874.html