标签:精确覆盖
Time Limit: 15s Memory Limit:
128MB
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
dupeng
精确覆盖模板题
/*************************************************************************
> File Name: hust1017.cpp
> Author: ALex
> Mail: 405045132@qq.com
> Created Time: 2015年01月05日 星期一 19时17分39秒
************************************************************************/
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
int k;
int U[N * N], D[N * N], L[N * N], R[N * N];
int C[N * N], ans[N];
int cntr[N], cntc[N];
int head;
int row[N][N]; //表示第i行第j个为1的列是多少
int col[N][N]; //表示第i列第j个为1的行是多少
int n, m;
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];
cntc[C[j]]--;
}
}
}
void resume(int c)
{
L[R[c]] = c;
R[L[c]] = c;
for (int i = D[c]; i != c; i = D[i])
{
for (int j = R[i]; j != i; j = R[j])
{
U[D[j]] = j;
D[U[j]] = j;
cntc[C[j]]++;
}
}
}
bool dance()
{
if (R[head] == head)
{
return true;
}
int c;
int mins = 0x3f3f3f3f;
for (int i = R[head]; i != head; i = R[i])
{
if (mins > cntc[i])
{
c = i;
mins = cntc[i];
}
}
remove(c);
for (int i = D[c]; i != c; i = D[i])
{
ans[k++] = (i - 1) / m;
for (int j = R[i]; j != i; j = R[j])
{
remove(C[j]);
}
if (dance())
{
return true;
}
for (int j = L[i]; j != i; j = L[j])
{
resume(C[j]);
}
k--;
}
resume(c);
return false;
}
bool build()
{
head = 0;
for (int i = 0; i < m; ++i)
{
R[i] = i + 1;
L[i + 1] = i;
}
R[m] = 0;
L[0] = m;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j < cntr[i]; ++j)
{
R[row[i][j]] = row[i][j + 1];
L[row[i][j + 1]] = row[i][j];
}
R[row[i][cntr[i]]] = row[i][1];
L[row[i][1]] = row[i][cntr[i]];
}
for (int i = 1; i <= m; ++i)
{
for (int j = 1; j < cntc[i]; ++j)
{
D[col[i][j]] = col[i][j + 1];
U[col[i][j + 1]] = col[i][j];
}
D[col[i][cntc[i]]] = i;
D[i] = col[i][1];
U[i] = col[i][cntc[i]];
U[col[i][1]] = i;
if (cntc[i] == 0)
{
return false;
}
}
return true;
}
int main()
{
int tmp;
while (~scanf("%d%d", &n, &m))
{
for (int i = 1; i <= m; ++i)
{
cntc[i] = 0;
}
for (int i = 1; i <= n; ++i)
{
scanf("%d", &cntr[i]);
for (int j = 1; j <= cntr[i]; ++j)
{
scanf("%d", &tmp);
row[i][j] = tmp + i * m;
cntc[tmp]++;
col[tmp][cntc[tmp]] = tmp + i * m;
C[tmp + i * m] = tmp;
}
}
if (build())
{
k = 0;
if (dance())
{
printf("%d", k);
for (int i = 0; i < k; ++i)
{
printf(" %d", ans[i]);
}
printf("\n");
}
else
{
printf("NO\n");
}
}
else
{
printf("NO\n");
}
}
return 0;
}标签:精确覆盖
原文地址:http://blog.csdn.net/guard_mine/article/details/42433201