【HDU】3498 whosyourdaddy 重复覆盖入门题

来源:互联网 发布:泛洪填充算法 编辑:程序博客网 时间:2024/05/22 08:28

传送门:【HDU】3498 whosyourdaddy


题目分析:重复覆盖入门题。

重复覆盖相对于精确覆盖有些地方不同,精确覆盖每次可以删除多行多列,但是重复覆盖每次只能删除一行多列,而且还需要可行性剪枝才能跑的稍微快一点。


代码如下:


#include <cstdio>#include <cstring>#include <algorithm>using namespace std ;#define REP( i , a , b ) for ( int i = a ; i < b ; ++ i )#define REV( i , a , b ) for ( int i = a - 1 ; i >= b ; -- i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define FOV( i , a , b ) for ( int i = a ; i >= b ; -- i )#define CLR( a , x ) memset ( a , x , sizeof a )#define REC( i , A , o ) for ( int i = A[o] ; i != o ; i = A[i] )const int MAXR = 60 ;const int MAXC = 60 ;const int MAXNODE = 4000 ;const int INF = 0x3f3f3f3f ;struct DLX {int U[MAXNODE] , D[MAXNODE] , L[MAXNODE] , R[MAXNODE] ;int row[MAXNODE] , col[MAXNODE] ;int S[MAXC] , H[MAXR] ;int vis[MAXC] ;int n , m ;int deep ;int size ;int G[MAXR][MAXC] ;void init () {CLR ( H , -1 ) ;FOR ( i , 0 , n ) {S[i] = 0 ;U[i] = i ;D[i] = i ;L[i] = i - 1 ;R[i] = i + 1 ;}L[0] = n ;R[n] = 0 ;size = n ;deep = INF ;}void link ( int r , int c ) {++ size ;++ S[c] ;row[size] = r ;col[size] = c ;U[size] = U[c] ;D[size] = c ;D[U[c]] = size ;U[c] = size ;if ( ~H[r] ) {L[size] = L[H[r]] ;R[size] = H[r] ;L[R[size]] = size ;R[L[size]] = size ;}elseH[r] = L[size] = R[size] = size ;}void remove ( int c ) {REC ( i , D , c ) {L[R[i]] = L[i] ;R[L[i]] = R[i] ;}}void resume ( int c ) {REC ( i , U , c ) {R[L[i]] = i ;L[R[i]] = i ;}}int h () {int cnt = 0 ;CLR ( vis , 0 ) ;REC ( i , R , 0 )if ( !vis[i] ) {++ cnt ;vis[i] = 1 ;REC ( j , D , i )REC ( k , R , j )vis[col[k]] = 1 ;}return cnt ;}void dance ( int d ) {if ( d + h () >= deep )return ;if ( R[0] == 0 ) {deep = min ( deep , d ) ;return ;}int c = R[0] ;REC ( i , R , 0 )if ( S[c] > S[i] )c = i ;REC ( i , D , c ) {remove ( i ) ;REC ( j , R , i )remove ( j ) ;dance ( d + 1 ) ;REC ( j , L , i )resume ( j ) ;resume ( i ) ;}}void solve () {int u , v ;init () ;CLR ( G , 0 ) ;REP ( i , 0 , m ) {scanf ( "%d%d" , &u , &v ) ;G[u][v] = G[v][u] = 1 ;}FOR ( i , 1 , n )FOR ( j , 1 , n )if ( G[i][j] || i == j )link ( i , j ) ;dance ( 0 ) ;printf ( "%d\n" , deep ) ;}} dlx ;int main () {while ( ~scanf ( "%d%d" , &dlx.n , &dlx.m ) )dlx.solve () ;return 0 ;}


0 0