开始学习dancing links了,01矩阵覆盖,居然搞了一中午+半个下午。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 22
#define MAXN 100005
#define mod 1000007
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
typedef long long ll;
using namespace std;
#define N 1005
#define M N*N
int U[M],D[M],L[M],R[M];
int ID[M],row[M],S[N],ans[N];
int k_ans;
void remove(int c)
{
int i,j;
L[R[c]]=L[c];
R[L[c]]=R[c];
for(i=D[c];i!=c;i=D[i]){
for(j=R[i];j!=i;j=R[j]){
U[D[j]]=U[j];
D[U[j]]=D[j];
S[ID[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]]=D[U[j]]=j;
S[ID[j]]++;
}
}
R[L[c]]=L[R[c]]=c;
}
void init(int n,int m)
{
memset(S,0,sizeof(S));
for(int i=1;i<=m;i++)
{
U[i]=D[i]=L[i+1]=R[i-1]=i;
}
R[m]=0;
}
bool dfs(int k)
{
// printf("%d\n",k);
if(!R[0]) {k_ans=k;return true;}
int tmp,mins=0x7fffffff;
for(int i=R[0];i;i=R[i])
{
if(S[i]<mins)
{
mins=S[i];
tmp=i;
}
}
remove(tmp);
for(int i=D[tmp];i!=tmp;i=D[i]) //选row[i]行
{
for(int j=R[i];j!=i;j=R[j])
{
remove(ID[j]);
}
ans[k]=row[i];
if(dfs(k+1)) return true;
for(int j=L[i];j!=i;j=L[j])
{
resume(ID[j]);
}
}
resume(tmp);
return false;
}
int main()
{
int n,m,k,a,top,base;
while(~scanf("%d%d",&n,&m))
{
init(n,m);
top=m+1;
for(int i=1;i<=n;i++)
{
scanf("%d",&k);
for(int j=1;j<=k;j++)
{
scanf("%d",&a);
S[a]++;
ID[top]=a;row[top]=i;
U[top]=U[a];D[U[a]]=top; //插入列
U[a]=top;D[top]=a;
if(j==1) {L[top]=R[top]=top;base=top;} //插入行
else
{
L[top]=L[base];R[L[base]]=top;
L[base]=top;R[top]=base;
}
top++;
}
}
if(dfs(0))
{
printf("%d",k_ans);
for(int i=0;i<k_ans;i++) printf(" %d",ans[i]);
puts("");
}
else puts("NO");
}
return 0;
}