题目可以将每一个格子都看做是一列,每一个矩形作为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 }

 

 posted on 2015-05-16 20:19  Love风吟  阅读(184)  评论(0编辑  收藏  举报