zju 3209 dancing links 求取最小行数

题目可以将每一个格子都看做是一列,每一个矩形作为1行,将所有格子进行标号,在当前矩形中的格子对应行的标号为列,将这个点加入到十字链表中

最后用dlx求解精确覆盖即可,dance()过程中记得剪枝

  1 #include <iostream>

  2 #include <cstring>

  3 #include <cstdio>

  4 #include <algorithm>

  5 #include <queue>

  6 #include <climits>

  7 

  8 using namespace std;

  9 #define N 1005

 10 #define M 505

 11 #define MAXNODE 500100

 12 const int INF = INT_MAX;

 13 

 14 struct DLX{

 15     int n,m,size;

 16     int L[MAXNODE] , R[MAXNODE] , U[MAXNODE] , D[MAXNODE];

 17     int col[MAXNODE] , row[MAXNODE] , first[M];

 18     int cnt_col[N];

 19     int ans;

 20 

 21     void init(int _n , int _m)

 22     {

 23         n=_n , m=_m , size = _m , ans=INF;

 24         for(int i=0 ; i<=m ; i++){

 25             U[i] = D[i] = i;

 26             L[i] = i-1 , R[i] = i+1;

 27         }

 28         L[0] = m , R[m] = 0;

 29         for(int i=1 ; i<=n ; i++) first[i] = -1;

 30         for(int i=1 ; i<=m ; i++) cnt_col[i] = 0;

 31     }

 32 

 33     void link(int r , int c)

 34     {

 35         ++size;

 36         D[size] = D[c] , U[D[c]] = size;

 37         U[size] = c , D[c] = size;

 38         cnt_col[c]++;

 39 

 40         if(first[r]<0){

 41             first[r] = size;

 42             L[size]= R[size] = size;

 43         }

 44         else{

 45             R[size] = R[first[r]] , L[R[first[r]]] = size;

 46             L[size] = first[r] , R[first[r]] = size;

 47         }

 48         row[size]=r , col[size]=c;

 49     }

 50 

 51     void Remove(int c)

 52     {

 53         L[R[c]] = L[c] , R[L[c]] = R[c];

 54         for(int i=D[c] ; i!=c ; i=D[i]){

 55             for(int j=R[i] ; j!=i ; j=R[j]){

 56                 D[U[j]] = D[j] , U[D[j]] = U[j];

 57                 --cnt_col[col[j]];

 58             }

 59         }

 60     }

 61 

 62     void Resume(int c)

 63     {

 64         for(int i=U[c] ; i!=c ; i=U[i]){

 65             for(int j=L[i] ; j!=i ; j=L[j]){

 66                 U[D[j]] = D[U[j]] = j;

 67                 ++cnt_col[col[j]];

 68             }

 69         }

 70         R[L[c]] = L[R[c]] = c;

 71     }

 72 

 73     void Dance(int d)

 74     {

 75         if(d>=ans) return;

 76         if(!R[0]){

 77             ans = min(ans , d);

 78             return;

 79         }

 80         int st = R[0];

 81         for(int i=st ; i!=0 ; i=R[i])

 82             if(cnt_col[st]>cnt_col[i]) st = i;

 83 

 84         Remove(st);

 85         for(int i=D[st] ; i!=st ; i=D[i]){

 86             for(int j=R[i] ; j!=i ; j=R[j]) Remove(col[j]);

 87             Dance(d+1);

 88             for(int j=L[i] ; j!=i ; j=L[j]) Resume(col[j]);

 89         }

 90         Resume(st);

 91     }

 92 }dlx;

 93 

 94 int main()

 95 {

 96    // freopen("a.in" , "r" , stdin);

 97     int T;

 98     scanf("%d" , &T);

 99     while(T--)

100     {

101         int n,m,p;

102         scanf("%d%d%d" , &n , &m , &p);

103         dlx.init(p , n*m);

104         for(int i=1 ; i<=p ; i++){

105             int x1,y1,x2,y2;

106             scanf("%d%d%d%d" , &x1 , &y1 , &x2 , &y2);

107             for(int j=x1+1 ; j<=x2 ; j++){

108                 for(int k=y1+1 ; k<=y2 ; k++){

109                     dlx.link(i , (k-1)*n+j);

110                 }

111             }

112         }

113         dlx.Dance(0);

114         if(dlx.ans == INF) puts("-1");

115         else printf("%d\n" , dlx.ans);

116     }

117     return 0;

118 }

 

你可能感兴趣的:(link)