Problem 1686 神龙的难题
Accept: 822 Submit: 2429
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
Input
Output
Sample Input
4 41 0 0 10 1 1 00 1 1 01 0 0 12 24 4 0 0 0 00 1 1 00 1 1 00 0 0 02 2
Sample Output
41
Source
FOJ月赛-2009年2月- TimeLoop
解题思路:舞蹈链
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cctype>
#include <map>
#include <cmath>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
const int maxn = 300005;
int n, m, x, y, tot;
int a[20][20];
struct DLX
{
int L[maxn], R[maxn], U[maxn], D[maxn];
int row[maxn], col[maxn], sum[maxn], ans[maxn];
int n, m, num, cnt;
int vis[maxn], flag[maxn];
void add(int k, int l, int r, int u, int d, int x, int y)
{
L[k] = l; R[k] = r; U[k] = u;
D[k] = d; row[k] = x; col[k] = y;
}
void reset(int n, int m)
{
this->n = n; this->m = m;
for (int i = 0; i <= m; i++)
{
add(i, i - 1, i + 1, i, i, 0, i);
sum[i] = 0;
}
L[0] = m, R[m] = 0, cnt = m + 1;
}
void insert(int x, int y)
{
int temp = cnt - 1;
if (row[temp] != x)
{
add(cnt, cnt, cnt, U[y], y, x, y);
U[D[cnt]] = cnt; D[U[cnt]] = cnt;
}
else
{
add(cnt, temp, R[temp], U[y], y, x, y);
R[L[cnt]] = cnt; L[R[cnt]] = cnt;
U[D[cnt]] = cnt; D[U[cnt]] = cnt;
}
sum[y]++, cnt++;
}
void Remove(int k)
{
for (int i = D[k]; i != k; i = D[i])
{
L[R[i]] = L[i];
R[L[i]] = R[i];
}
}
void Resume(int k)
{
for (int i = U[k]; i != k; i = U[i]) L[R[i]] = R[L[i]] = i;
}
int A()
{
int dis = 0;
for (int i = R[0]; i != 0; i = R[i]) vis[i] = 0;
for (int i = R[0]; i != 0; i = R[i])
if (!vis[i])
{
dis++, vis[i] = 1;
for (int j = D[i]; j != i; j = D[j])
for (int k = R[j]; k != j; k = R[k])
vis[col[k]] = 1;
}
return dis;
}
void Dfs(int k)
{
if (!R[0]) num = min(num, k);
else if (k + A() < num)
{
int now = R[0];
for (int i = R[0]; i != 0; i = R[i])
if (sum[now] > sum[i]) now = i;
for (int i = D[now]; i != now; i = D[i])
if (!flag[row[i] ^ 1])
{
Remove(i);
for (int j = R[i]; j != i; j = R[j]) Remove(j);
Dfs(k + 1);
for (int j = L[i]; j != i; j = L[j]) Resume(j);
Resume(i);
}
}
}
void mul()
{
memset(flag, 0, sizeof flag);
num = 0x7FFFFFFF;
}
}dlx;
int main()
{
while (~scanf("%d%d", &n, &m))
{
tot = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
scanf("%d", &a[i][j]);
tot += a[i][j];
if (a[i][j]) a[i][j] = tot;
}
scanf("%d%d", &x, &y);
dlx.reset((n - x + 1)*(m - y + 1), tot);
tot = 0;
for (int i = 1; i + x - 1 <= n; i++)
for (int j = 1; j + y - 1 <= m; j++)
{
tot++;
for (int k = 0; k < x; k++)
for (int p = 0; p < y; p++)
if (a[k + i][p + j]) dlx.insert(tot, a[k + i][p + j]);
}
dlx.mul();
dlx.Dfs(0);
printf("%d\n", dlx.num);
}
return 0;
}