dancinglinks学到的人,桑不起呀,囧~~~
DancingLinks果题,俺就不啰嗦了,囧~~~
2012-10-23//题目链接http://acm.hust.edu.cn:8080/judge/problem/viewProblem.action?id=10702
#include"stdio.h" #include"string.h" #include"stdlib.h" #include"math.h" #define N 2222 #define V 1111111 int n,m; int S[N]; int L[V],R[V],U[V],D[V],C[V],H[V]; int c_T[N],h_T[N]; int head,base; int Ans,ans[N],flag; void Link(int r,int c) { int t; t=(r-1)*m+c+base; //行列头的 C[t]=c;H[t]=m+r;/*是m+r*/S[c]++; //t的 U[t]=c_T[c];D[t]=c; L[t]=h_T[m+r];/*是m+r*/R[t]=m+r; //上一个t的 U[c]=t; D[c_T[c]]=t; L[m+r]=t; R[h_T[m+r]]=t; //next c_T[c]=t; h_T[m+r]=t; } void remove(int c) { int i,j; R[L[c]]=R[c]; L[R[c]]=L[c]; for(i=D[c];i!=c;i=D[i]) { for(j=R[i];j!=i;j=R[j]) { D[U[j]]=D[j]; U[D[j]]=U[j]; S[C[j]]--; } } } void resume(int c) { int i,j; for(i=U[c];i!=c;i=U[i]) { for(j=L[i];j!=i;j=L[j]) { U[D[j]]=j; D[U[j]]=j; S[C[j]]++; } } R[L[c]]=c; L[R[c]]=c; } void Dance(int k) { int i,l,j; int c,t=111111111; if(flag) return ; if(R[head]==head) { flag=1; return ; } for(i=R[head];i!=head;i=R[i]) { if(S[i]<t) { c=i; t=S[i]; } } remove(c); for(i=D[c];i!=c;i=D[i]) { ans[k]=H[i];Ans=k+1; for(j=R[i];j!=i;j=R[j]) { if(m<j && j<=m+n) continue; remove(C[j]); } Dance(k+1); if(flag) return ; for(j=L[i];j!=i;j=L[j]) { if(m<j && j<=m+n) continue; resume(C[j]); } } resume(c); } int main() { int i,l; int c,t,temp; while(scanf("%d%d",&n,&m)!=-1) { memset(S,0,sizeof(S)); head=0; L[head]=m;R[head]=1; U[head]=m+n;D[head]=m+1; for(i=1;i<=m;i++) { L[i]=i-1; R[i-1]=i; C[i]=U[i]=D[i]=i; c_T[i]=i; } R[m]=0; for(i=m+2;i<=m+n;i++) { U[i]=i-1; D[i-1]=i; H[i]=L[i]=i;R[i]=i; h_T[i]=i; } U[m+1]=0;h_T[m+1]=m+1; D[m+n]=0; base=n+m; for(i=1;i<=n;i++) { scanf("%d",&c); while(c--) { scanf("%d",&t); Link(i,t); } } flag=0; Ans=0; Dance(0); if(!flag) printf("NO\n"); else { printf("%d",Ans); for(i=0;i<Ans;i++) printf(" %d",ans[i]-m); printf("\n"); } } return 0; }