ZOJ 3209 Treasure Map(舞蹈链)
2016-02-21 18:50
197 查看
题目链接:[kuangbin带你飞]专题三 Dancing Links B - Treasure Map
题意
给一矩形和k个小矩形,问选取最小数量为多少的小矩形可以对大矩形进行精确覆盖。思路
仍然是个模版题,把二维的n*m的大矩形看作是一维的n*m的一条线。k个小矩形同理,那么就转化成01矩阵精确覆盖的问题了。代码
[code]#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cstdlib> #include <vector> using namespace std; const int N = 1009; const int MAX = 1000009; int U[MAX], D[MAX], L[MAX], R[MAX];//数组模拟链表指向(上下左右) int C[MAX], M[MAX];//节点所在列与行 int S ;//储存每列的元素数量 int H ;//行头指针 int ans; void init(int n, int m) { for(int i=0; i<=m; i++) { L[i+1] = i; R[i] = i+1; U[i] = D[i] = i; S[i] = 0; } for(int i=1; i<=n; i++) H[i] = -1; L[0] = m; R[m] = 0; } void link(int row, int col, int id)//将节点加入链表 { C[id] = col; M[id] = row;//记录行列 U[id] = U[col]; D[U[col]] = id;//上下连接 D[id] = col; U[col] = id; if(H[row] == -1)//左右连接(使用表头方便头插) H[row] = L[id] = R[id] = id; else { L[id] = L[H[row]]; R[L[H[row]]] = id; L[H[row]] = id; R[id] = H[row]; } S[col]++; } void remove(int col)//删除列 { R[L[col]] = R[col]; L[R[col]] = L[col]; for(int i=D[col]; i!=col; i=D[i]) { for(int j=R[i]; j!=i; j=R[j]) { U[D[j]] = U[j]; D[U[j]] = D[j]; S[C[j]]--; } } } void resume(int col)//恢复列(先删的后恢复,后删的先恢复,所以跟remove反向操作) { R[L[col]] = col; L[R[col]] = col; for(int i=U[col]; i!=col; i=U[i]) { for(int j=L[i]; j!=i; j=L[j]) { U[D[j]] = j; D[U[j]] = j; S[C[j]]++; } } } void dance(int k) { if(ans!=-1 && k>=ans) return; if(!R[0]) { ans = k; return; } int col = R[0]; for(int i=R[0]; i!=0; i=R[i]) if(S[i] < S[col]) col = i; remove(col); for(int i=D[col]; i!=col; i=D[i]) { for(int j=R[i]; j!=i; j=R[j]) remove(C[j]); dance(k+1); for(int j=L[i]; j!=i; j=L[j]) resume(C[j]); } resume(col); } int main() { int n, m, k, T; scanf("%d", &T); while(T--) { scanf("%d%d%d", &n, &m, &k); init(k, n*m); int id = n*m+1; for(int i=1; i<=k; i++) { int x1, x2, y1, y2; scanf("%d%d%d%d", &x1, &y1, &x2, &y2); for(int x=x1+1; x<=x2; x++) for(int y=y1+1; y<=y2; y++) link(i, y+(x-1)*m, id++); } ans = -1; dance(0); printf("%d\n", ans); } return 0; }
相关文章推荐
- [Lintcode]Median
- 多项式求和
- 2015-2016寒假 第三周学习总结
- UTF8和GB2312的相互转换
- 函数重载
- 文件操作
- 浅谈JavaScript的全局变量跟局部变量
- 怎样安装pip--python的包管理工具
- CIFilter (模糊图片)
- js常用功能工具库--Underscore.js
- os_core.c
- 默认参数和占位参数
- static静态变量分析
- 执行shell脚本提示“syntax error near unexpected token for((i=0;i<$length;i++))”
- python的列表,元组和字典简单介绍
- 【小镇的技术天梯】Scapy学习日记(三)
- 操作系统(死锁)
- LeetCode OJ - Search for a Range
- 深入浅出-iOS的TCP/IP协议族剖析&&Socket
- Redis消息队列发布微博