poj 3740 Easy Finding
2014-01-15 00:00
477 查看
摘要: 第一道dancing links,纪念下~
第一道dancing links,纪念下~
[Submit] [Go Back] [Status] [Discuss]
第一道dancing links,纪念下~
Easy Finding
Given a M× N matrix A. A ij ∈ {0, 1} (0 ≤ i < M, 0 ≤ j < N), could you find some rows that let every cloumn contains and only contains one 1. Input There are multiple cases ended by EOF. Test case up to 500.The first line of input is M, N ( M ≤ 16, N ≤ 300). The next M lines every line contains N integers separated by space. Output For each test case, if you could find it output "Yes, I found it", otherwise output "It is impossible" per line. Sample Input 3 3 0 1 0 0 0 1 1 0 0 4 4 0 0 0 1 1 0 0 0 1 1 0 1 0 1 0 0Sample Output Yes, I found it It is impossibleSource POJ Monthly Contest - 2009.08.23, MasterLuo |
#include <cstdio> #include <cstdlib> #include <string> #include <cstring> #include <algorithm> #define maxn 5200 #define maxl 305 #define maxm 18 #define head 0 //数组实现的dancing links int up[maxn] = {0}, down[maxn] = {0}, left[maxn] = {0}, right[maxn] = {0};//顾名思义是某个结点的上下左右结点的标号 int column[maxn] = {0}, row[maxn] = {0}, ans[maxn] = {0};//某个结点对应的行号,ans是取的行号的数组 int m = 0, n = 0; void init()//初始化 { memset(up, 0, sizeof(up)); memset(down, 0, sizeof(down)); memset(left, 0, sizeof(left)); memset(right, 0, sizeof(right)); memset(column, 0, sizeof(column)); memset(row, 0, sizeof(row)); memset(ans, 0, sizeof(ans)); return; } //这里的remove其实并没有真正删除掉结点,可以用resume恢复 void remove(int c)//去掉c号结点,以及在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]; } } return; } void resume(int c)//remove的逆操作 { left[right[c]] = c; right[left[c]] = c; for (int i = up[c]; i != c; i = up[i]) { for (int j = right[i]; j != i; j = right[j]) { up[down[j]] = j; down[up[j]] = j; } } return; } //我们的终极目标实际上是把十字链表中所有的结点都删掉,只留一个头结点 bool dance(int k)//这里的k实际上是没多大意义的 { int c = right[head]; if (c == head)//只剩下十字链表的头结点,则完成了目标 { return true; } remove(c); for (int i = down[c]; i != c; i = down[i])//这里其实是枚举某一行对待匹配行的第c位进行匹配 { ans[k] = row[i]; for (int j = right[i]; j != i; j = right[j]) remove(column[j]);//remove待匹配行的column[j]结点 if (dance(k + 1)) return true; for (int j = left[i]; j != i; j = left[j]) resume(column[j]); } resume(c); return false; } void test(int idn)//测试用 { printf("up do le ri co ro\n"); for (int i = 0; i < idn; ++i) { printf("%02d %02d %02d %02d %02d %02d\n", up[i], down[i], left[i], right[i], column[i], row[i]); } return; } int main() { while (scanf("%d%d", &m, &n) != EOF)//输入部分极其复杂 { init(); int id = 1; int tmp = 0; int lineup[maxl] = {0}; for (int j = 0; j < n; ++j)//待匹配行 { lineup[j] = id; column[id] = j + 1; if (j != n - 1) { right[id] = id + 1; } left[id] = id - 1; ++id; } right[head] = 1; left[head] = id - 1; right[id - 1] = head; for (int i = 0; i < m; ++i) { int first_id = 0; int left_id = 0; for (int j = 0; j < n; ++j) { scanf("%d", &tmp); if (tmp) { row[id] = i + 1; column[id] = j + 1; if (first_id == 0) { first_id = id; left_id = id; } else { left[id] = left_id; right[left_id] = id; left_id = id; } int upid = lineup[j]; up[id] = upid; down[upid] = id; lineup[j] = id; ++id; } } if (first_id != 0) { left[first_id] = left_id; right[left_id] = first_id; } } for (int j = 0; j < n; ++j) { down[lineup[j]] = j + 1; up[j + 1] = lineup[j]; } //test(id); int is_possible = dance(0); if (is_possible) printf("Yes, I found it\n"); else printf("It is impossible\n"); } return 0; }
相关文章推荐
- poj 3740 Easy Finding
- [ACM] POJ 3740 Easy Finding (DLX模板题)
- poj——3740 Easy Finding
- 【POJ】3740 Easy Finding 精确覆盖入门题
- poj 3740 Easy Finding 精确覆盖
- POJ 3740 Easy Finding
- [ACM] POJ 3740 Easy Finding (DLX模板题)
- poj3740 Easy Finding(深搜)
- poj - 3740 - Easy Finding(精确覆盖DLX)
- poj 3740 Easy Finding(Dancing Links 精确覆盖)
- [ACM] POJ 3740 Easy Finding (DFS)
- POJ 3740 Easy Finding (Exact cover problem)
- POJ-3740-Easy Finding【DLX精确覆盖】
- poj 3740 -- Easy Finding (dfs)
- [ACM] POJ 3740 Easy Finding (DFS)
- 【POJ】3740 Easy Finding
- POJ 3740 Easy Finding【Dancinglinks】
- poj 3740 Easy Finding
- POJ 3740 Easy Finding (DLX模板)
- POJ 3740 Easy Finding