p4929 DLX舞蹈链
前置知识 :十字链表
本质上是一种数据结构优化的暴力 主要是十字链表存稀疏图比较快
代码
#include<bits/stdc++.h> using namespace std; int n,m; int h[1000000],s[10000000],l[1000000],r[1000000],u[1000000],d[1000000],col[1000000],row[100000],ansk[1000000],cnt; void init(){ for(int i=0;i<=m;i++){ l[i]=i-1; r[i]=i+1; u[i]=d[i]=i; } l[0]=m; r[m]=0; memset(h,-1,sizeof h); memset(s,0,sizeof s); cnt=m+1; } void in(int i,int j){ s[j]++; row[cnt]=i; col[cnt]=j; u[cnt]=j; d[cnt]=d[j]; u[d[j]]=cnt; d[j]=cnt; if(h[i]==-1){ h[i]=l[cnt]=r[cnt]=cnt; }else{ l[cnt]=l[h[i]]; r[l[h[i]]]=cnt; r[cnt]=h[i]; l[h[i]]=cnt; } cnt++; } inline void del(int 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]]--; } } } inline void add(int C){ for(int i=u[C];i!=C;i=u[i]){ for(int j=l[i];j!=i;j=l[j]){ u[d[j]]=j; d[u[j]]=j; s[col[j]]++; } } r[l[C]]=C; l[r[C]]=C; } bool dance(int num){ if(r[0]==0){ for(int i=0;i<num;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; } } del(c); for(int i=d[c];i!=c;i=d[i]){ ansk[num]=row[i]; for(int j=r[i];j!=i;j=r[j]){ del(col[j]); } if(dance(num+1)){ return 1; } for(int j=l[i];j!=i;j=l[j]){ add(col[j]); } } add(c); return 0; } int main(){ scanf("%d%d",&n,&m); init(); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ int x; scanf("%d",&x); if(x){ in(i,j); } } } if(!dance(0)){ printf("No Solution!"); } }