FZU1686-神龙的难题

来源:互联网 发布:地震法术数据 编辑:程序博客网 时间:2024/04/28 16:23

                                             Problem 1686 神龙的难题

Accept: 822    Submit: 2429
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是个安宁的国家,人民安居乐业,魔物也比较少.但是.总有一些魔物不时会进入城市附近,干扰人民的生活.就要有一些人出来守护居民们不被魔物侵害.魔法使艾米莉就是这样的一个人.她骑着她的坐骑,神龙米格拉一起消灭干扰人类生存的魔物,维护王国的安定.艾米莉希望能够在损伤最小的前提下完成任务.每次战斗前,她都用时间停止魔法停住时间,然后米格拉他就可以发出火球烧死敌人.米格拉想知道,他如何以最快的速度消灭敌人,减轻艾米莉的负担.

 Input

数据有多组,你要处理到EOF为止.每组数据第一行有两个数,n,m,(1<=n,m<=15)表示这次任务的地区范围. 然后接下来有n行,每行m个整数,如为1表示该点有怪物,为0表示该点无怪物.然后接下一行有两个整数,n1,m1 (n1<=n,m1<=m)分别表示米格拉一次能攻击的行,列数(行列不能互换),假设米格拉一单位时间能发出一个火球,所有怪物都可一击必杀.

 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;}

原创粉丝点击