Easy finding
Time limit:1000 ms |
|
Memory limit:65536 K |
Total submissions:15668 |
|
Accepted:4163 |
Description GivenM×NMatrixA.AIJ ε {0, 1} (0 ≤ I <m, 0 ≤ j <n), cocould you find some rows that let every cloumn contains and only contains 1.Input There are multiple cases endedEOF. Test Case up to 500.the first line of input isM,N(M≤ 16,N≤ 300). The nextMLines every line containsNIntegers separated by space.Output For each test case, if you cocould find it output "Yes, I found it", otherwise output "It is impossible" per line.Sample Input 3 30 1 00 0 11 0 04 40 0 0 11 0 0 01 1 0 10 1 0 0 Sample output Yes, I found itIt is impossible Source Poj monthly contest-2009.08.23, masterluo |
Question:
Give you a matrix of N * m (n <= 16, m <= 300. Each element of the matrix can only be 0 or 1. Now, I ask if you can select some columns from the matrix so that none of the columns has only one.
Ideas:
Start to tease. Consider that there are only 16 questions in each row. It's fun to watch 16. This is a typical pressure. Compress each line into a binary number with a length of 16. Then the feasibility is determined. After finishing the RE. This also applies. M and n are all wrong. Because there are too many values in each line, you cannot press it. Rogue. Only Baidu. I learned that it was dancing links, So Baidu's data. Link One.
For details, see the code:
# Include <iostream> # include <stdio. h> using namespace STD; const int INF = 0x3f3f3f3f; const int maxn = 6010; int U [maxn], d [maxn], L [maxn], R [maxn], c [maxn]; // the pointer between top, bottom, and left. Column corresponding to node I in C [I. Int s [310], H [310]; // s [I] indicates the number of column 1. H [I] is the tail pointer of line I. Int n, m, CNT; void Init () {int I; for (I = 1; I <= N; I ++) H [I] =-1; for (I = 0; I <= m; I ++) {s [I] = 0; L [I + 1] = I; R [I] = I + 1; U [I] = d [I] = I;} R [m] = 0; CNT = m + 1 ;} void insert (int r, int c) {// create a chain table U [CNT] = c, d [CNT] = d [c]; // determine the upper and lower pointer information of the newly added node u [d [c] = CNT, d [c] = CNT; // restore the linked list information if (H [R] =-1) // determine the Left and Right pointer information H [R] = L [CNT] = R [CNT] = CNT; // Add the header else {L [CNT] = H [R], R [CNT] = R [H [R]; // header Insertion Method L [R [H [R] = CNT, R [H [R] = CNT;} s [c] ++; // update the Additional Information C [CNT ++] = C;} void remov E (INT c) // remove column C. {Int I, j; R [L [c] = R [c], L [R [c] = L [c]; for (I = d [c]; I! = C; I = d [I]) for (j = R [I]; J! = I; j = R [J]) d [U [J] = d [J], U [d [J] = U [J], s [C [J] --;} void resume (INT c) // restore the C column. {Int I, j; R [L [c] = L [R [c] = C; for (I = d [c]; I! = C; I = d [I]) for (j = R [I]; J! = I; j = R [J]) d [U [J] = U [d [J] = J, s [C [J] ++ ;} bool DFS () {If (R [0] = 0) return true; int I, j, C, miv = inf; for (I = R [0]; I; I = R [I]) if (s [I] <miv) miv = s [I], c = I; remove (C ); // process column C for (I = d [c]; I! = C; I = d [I]) {for (j = R [I]; J! = I; j = R [J]) Remove (C [J]); If (DFS () return true; For (j = L [I]; J! = I; j = L [J]) Resume (C [J]);} resume (c); Return false;} int main () {int op, I, J; while (~ Scanf ("% d", & N, & M) {Init (); for (I = 1; I <= N; I ++) for (j = 1; j <= m; j ++) {scanf ("% d", & OP); If (OP) insert (I, j );} if (DFS () printf ("Yes, I found it \ n"); else printf ("It is impossible \ n");} return 0 ;}