6 7 3 1 4 7 2 1 4 3 4 5 7 3 3 5 6 4 2 3 6 7 2 2 7
3 2 4 6
模版题。关于DLX的详细解说,请看博客文章DLX。
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const int MAXN = 1000+7;
const int MAXP = 1e6+7;
struct DLX
{
int n,m,Size;
int up[MAXP],down[MAXP],left[MAXP],right[MAXP],row[MAXP],col[MAXP];
int h[MAXN],s[MAXN];
int ansd,ans[MAXN];
//初始化
void init(int _n,int _m)
{
n = _n;
m = _m;
for(int i = 0; i <= m; ++i)
{
s[i] = 0;
up[i] = down[i] = i;
left[i] = i-1;
right[i] = i+1;
}
right[m] = 0;
left[0] = m;
Size = m;
for(int i = 1; i <= n; ++i)h[i] = -1;
}
//连接
void Link(int r,int c)
{
++s[col[++Size] = c];
row[Size] = r;
down[Size] = down[c];
up[down[c]] = Size;
up[Size] = c;
down[c] = Size;
if(h[r] < 0)h[r] = left[Size] = right[Size] = Size;
else
{
right[Size] = right[h[r]];
left[right[h[r]]] = Size;
left[Size] = h[r];
right[h[r]] = Size;
}
}
//删除c列
void Remove(int c)
{
left[right[c]] = left[c];
right[left[c]] = right[c];
for(int i = down[c]; i != c; i = down[i])
for(int j = right[i]; j != i; j = right[j])
{
up[down[j]] = up[j];
down[up[j]] = down[j];
--s[col[j]];
}
}
//撤销删除c列
void Resume(int c)
{
for(int i = up[c]; i != c; i = up[i])
for(int j = left[i]; j != i; j = left[j])
{
++s[col[up[down[j]] = down[up[j]] = j]];
}
right[left[c]] = left[right[c]] = c;
}
//递归判断,d为深度
bool Dance(int d)
{
if(right[0] == 0)
{
ansd = d;
return 1;
}
int c = right[0];
for(int i = right[0]; i; i = right[i])
if(s[i] < s[c])c = i;
Remove(c);
for(int i = down[c]; i != c; i = down[i])
{
ans[d] = row[i];
for(int j = right[i]; j != i; j = right[j])Remove(col[j]);
if(Dance(d+1))return 1;
for(int j = left[i]; j != i; j =left[j])Resume(col[j]);
}
Resume(c);
return 0;
}
};
DLX g;
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
g.init(n,m);
for(int i = 1; i <= n; ++i)
{
int num,j;
scanf("%d",&num);
while(num--)
{
scanf("%d",&j);
g.Link(i,j);
}
}
if(!g.Dance(0))puts("NO");
else
{
printf("%d",g.ansd);
for(int i = 0; i < g.ansd; ++i)printf(" %d",g.ans[i]);
puts("");
}
}
return 0;
}