Matrix_code

graph - DLX

Sep 16th, 2017 (edited)
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.33 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <vector>
  5. #include <algorithm>
  6. #include <assert.h>
  7. using namespace std;
  8. #define MAXV 0x3f3f3f3f
  9. #define MAXE 1048576
  10. #define MAXC 1048576
  11. #define MAXR 1024
  12. class DLX {
  13.     public:
  14.     struct DacingLinks {
  15.         int left, right;
  16.         int up, down;
  17.         int ch, rh;
  18.         int data; // extra info
  19.     } DL[MAXE];
  20.     int s[MAXC], o[MAXR], head, size, Ans, findflag;
  21.     void Remove(int c) {
  22.         static int i;
  23.         for(i = DL[c].down; i != c; i = DL[i].down) {
  24.             DL[DL[i].right].left = DL[i].left;
  25.             DL[DL[i].left].right = DL[i].right;
  26.             s[DL[i].ch]--;
  27.         }
  28.     }
  29.     void Resume(int c) {
  30.         static int i;
  31.         for(i = DL[c].down; i != c; i = DL[i].down) {
  32.             DL[DL[i].right].left = i;
  33.             DL[DL[i].left].right = i;
  34.             s[DL[i].ch]++;
  35.         }
  36.     }
  37.     int used[MAXC] = {};
  38.     int H() {
  39.         static int c, ret, i, j, time = 0;
  40.         for(c = DL[head].right, ++time, ret = 0; c != head; c = DL[c].right) {
  41.             if(used[c] != time) {
  42.                 ret ++, used[c] = time;
  43.                 for(i = DL[c].down; i != c; i = DL[i].down)
  44.                     for(j = DL[i].right; j != i; j = DL[j].right)
  45.                         used[DL[j].ch] = time;
  46.             }
  47.         }
  48.         return ret;
  49.     }
  50.     void DFS(int k) {
  51.         if(k + H() >= Ans) return;
  52.         if(DL[head].right == head) {
  53.             Ans = min(Ans, k);
  54.             return;
  55.         }
  56.         int t = MAXV, c = 0, i, j;
  57.         for(i = DL[head].right; i != head; i = DL[i].right) {
  58.             if(s[i] < t) {
  59.                 t = s[i], c = i;
  60.             }
  61.         }
  62.         for(i = DL[c].down; i != c; i = DL[i].down) {
  63.             o[k] = i;
  64.             Remove(i);
  65.             for(j = DL[i].right; j != i; j = DL[j].right) Remove(j);
  66.             DFS(k+1);
  67.             for(j = DL[i].left; j != i; j = DL[j].left) Resume(j);
  68.             Resume(i);
  69.             if (findflag) break;
  70.         }
  71.     }
  72.     int new_node(int up, int down, int left, int right) {
  73.         assert(size < MAXE);
  74.         DL[size].up = up, DL[size].down = down;
  75.         DL[size].left = left, DL[size].right = right;
  76.         DL[up].down = DL[down].up = DL[left].right = DL[right].left = size;
  77.         return size++;
  78.     }
  79.     void addrow(int n, int Row[], int data) {
  80.         int a, r, row = -1, k;
  81.         for(a = 0; a < n; a++) {
  82.             r = Row[a];
  83.             DL[size].ch = r, s[r]++;
  84.             DL[size].data = data;
  85.             if(row == -1) {
  86.                 row = new_node(DL[DL[r].ch].up, DL[r].ch, size, size);
  87.                 DL[row].rh = a;
  88.             }else {
  89.                 k = new_node(DL[DL[r].ch].up, DL[r].ch, DL[row].left, row);
  90.                 DL[k].rh = a;
  91.             }
  92.         }
  93.     }
  94.     void init(int m) {
  95.         size = 0;
  96.         head = new_node(0, 0, 0, 0);
  97.         int i;
  98.         for(i = 1; i <= m; i++) {
  99.             new_node(i, i, DL[head].left, head);
  100.             DL[i].ch = i, s[i] = 0;
  101.         }
  102.     }
  103. } dlx;
  104.  
  105. int main() {
  106.     int testcase;
  107.     int n, m, x;
  108.     scanf("%d", &testcase);
  109.     while (testcase--) {
  110.         scanf("%d", &n);
  111.         assert(n * n < MAXC);
  112.         int label = 0, hLabel[16][16], vLabel[16][16];
  113.         int enable[2048], cover_col = 0;
  114.         vector<int> g[2048];
  115.         for (int i = 1; i <= n + 1; i++) {
  116.             for (int j = 1; j <= n; j++)
  117.                 hLabel[i][j] = ++label, enable[label] = 1;
  118.             for (int j = 1; j <= n + 1; j++)
  119.                 vLabel[i][j] = ++label, enable[label] = 1;
  120.         }
  121.         for (int k = 0; k <= n; k++) {
  122.             for (int i = 1; i+k <= n; i++) {
  123.                 for (int j = 1; j+k <= n; j++) {
  124.                     cover_col++;
  125.                     for (int l = 0; l <= k; l++) {
  126.                         g[hLabel[i][j+l]].push_back(cover_col);
  127.                         g[hLabel[i+1+k][j+l]].push_back(cover_col);
  128.                         g[vLabel[i+l][j]].push_back(cover_col);
  129.                         g[vLabel[i+l][j+1+k]].push_back(cover_col);
  130. //                        printf("%d %d %d %d\n", hLabel[i][j+l], hLabel[i+1+k][j+l],
  131. //                                    vLabel[i+l][j], vLabel[i+l][j+1+k]);
  132.                     }
  133. //                    puts("--");
  134.                 }
  135.             }
  136.         }
  137.         dlx.init(cover_col);
  138.         scanf("%d", &m);
  139.         for (int i = 0; i < m; i++) {
  140.             scanf("%d", &x);
  141.             enable[x] = 0;
  142.         }
  143.         int cover[2048] = {}, preCover = 0;
  144.         int row[2028], rowSize = 0;
  145.         for (int i = 1; i <= label; i++) {
  146.             if (!enable[i] || g[i].size() == 0) {
  147.                 for (int j = 0; j < g[i].size(); j++)
  148.                     cover[g[i][j]] = 1;
  149.                 continue;
  150.             }
  151.             rowSize = 0;
  152.             for (int j = 0; j < g[i].size(); j++)
  153.                 row[rowSize++] = g[i][j];
  154.             dlx.addrow(rowSize, row, i);
  155.         }
  156.         rowSize = 0;
  157.         for (int i = 1; i <= cover_col; i++) {
  158.             if (cover[i])
  159.                 row[rowSize++] = i, preCover = 1;
  160.         }
  161.         if (preCover)
  162.             dlx.addrow(rowSize, row, label + 1);
  163.         dlx.Ans = 0x3f3f3f3f;
  164.         dlx.DFS(0);
  165.         printf("%d\n", dlx.Ans - preCover);
  166.     }
  167.     return 0;
  168. }
Add Comment
Please, Sign In to add comment