存个dancing links的板子,万分感谢r_clover君的指导。。
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<bitset>
using namespace std;
const int maxn=1000*100*2+30;
struct rec
{
int L[maxn],R[maxn],U[maxn],D[maxn];
int Row[maxn],Col[maxn];
int h[maxn],s[maxn];
int si;
vector<int> ans;
void init(int m)
{
for (int i=0;i<=m;i++)
{
U[i]=D[i]=i;
L[i]=i-1;
R[i]=i+1;
s[i]=0;
}
L[0]=m;
R[m]=0;
memset(h,-1,sizeof(h));
si=m;
ans.clear();
}
void link(int row,int col)
{
si++;
Col[si]=col;Row[si]=row;
s[col]++;
U[si]=U[col];D[si]=col;
D[U[col]]=si;
U[col]=si;
if (h[row]!=-1)
{
R[si]=h[row];
L[si]=L[h[row]];
R[L[si]]=si;
L[R[si]]=si;
}
else
h[row]=L[si]=R[si]=si;
}
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])
{
U[D[j]]=j;
D[U[j]]=j;
s[Col[j]]++;
}
R[L[c]]=c;
L[R[c]]=c;
}
bool dfs()
{
if (R[0]==0) return true;
int c=R[0];
remove(c);
for (int i=D[c];i!=c;i=D[i])
{
ans.push_back(Row[i]);
for (int j=R[i];j!=i;j=R[j])
remove(Col[j]);
if (dfs()) return true;
for (int j=L[i];j!=i;j=L[j])
resume(Col[j]);
ans.pop_back();
}
resume(c);
return false;
}
}dlx;
int main()
{
freopen("test.in","r",stdin);
int n,m;
while (~scanf("%d%d",&n,&m))
{
dlx.init(m);
int a,b;
for (int i=1;i<=n;i++)
{
scanf("%d",&a);
while (a--)
{
scanf("%d",&b);
dlx.link(i,b);
}
}
if (dlx.dfs())
{
vector<int> ans=dlx.ans;
sort(ans.begin(),ans.end());
printf("%d",ans.size());
for (int i=0;i<ans.size();i++)
printf(" %d",ans[i]);
printf("\n");
}
else printf("NO\n");
}
return 0;
}