题目可以将每一个格子都看做是一列,每一个矩形作为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 }
我还在坚持,我还未达到我所想,梦~~一直在