Code[VS] 1022 覆盖 题解

Code[VS] 1022 覆盖 题解


题目传送门:Code[VS] 1022
题目描述 Description

有一个N×M的单位方格中,其中有些方格是水塘,其他方格是陆地。如果要用1×2的矩阵区覆盖(覆盖过程不容许有任何部分重叠)这个陆地,那么最多可以覆盖多少陆地面积。

输入描述 Input Description

输入文件的第一行是两个整数NM  (1<=NM<=100),第二行为一个整数K( K<=50),接下来的K行,每行两个整数X,Y表示K个水塘的行列位置。(1<=X<=N1<=Y<=M)。

输出描述 Output Description

输出所覆盖的最大面积块(1×2面积算一块)。

样例输入 Sample Input

4 4

6

1 1

1 4

2 2

4 1

4 2

4 4

样例输出 Sample Output

4

____________________________________分割线_____________________________________

分析:

将矩形的每一块分为 0 , 1 两个集合,相邻的两块属于不同的集合,如下图:

这时,这个问题就转化为一个典型的二分图匹配,可以使用Hungary Algorithm 解决。

 

代码:

 1 #include "cstdio"
 2 #include "cstring"
 3 #include "algorithm"
 4 
 5 using namespace std ;
 6 const int maxN = 210 ;
 7 const int INF = 2147483647 ; 
 8 
 9 bool wat[ maxN ][ maxN ] , map[ maxN ][ maxN ] , used[ maxN ][ maxN ] ;
10 
11 int N , M , k , ans , px , py ;
12 
13 int from[ maxN ][ maxN ][ 2 ] ;
14 
15 int _1[ 5 ] = { 0 , 1 , -1 , 0 , 0 } , _2[ 5 ] = { 0 , 0 , 0 , 1 , -1 } ;//方向 
16 
17 bool find ( int x , int y ) 
18 {
19     int px , py ;
20     for(int i=1 ; i<=4 ; ++i )
21     {
22         px = x + _1[i] ,py = y + _2[i];
23         if( px<=0 || px>N || py<=0 || py>M || wat[ px ][ py ] ) continue ;
24         if ( !wat[ px ][ py ] && !used[ px ][ py ] && !map[ px ][ py ])
25         {
26             used[ px ][ py ] = true ;
27             if( ( !from[ px ][ py ][ 0 ] ) || (find( from[ px ][ py ][ 0 ] , from[ px ][ py ][ 1 ] ) ) ) 
28             {
29                 from[ px ][ py ][ 0 ] = x ;
30                 from[ px ][ py ][ 1 ] = y ;
31                 return true ;
32             } 
33         }
34     }
35     return false ;
36 }
37 int main()
38 {
39     scanf( "%d%d%d" , &N , &M , &k ) ;
40     for(int i=1 ; i<=k ; ++i )
41     {
42         int _x , _y ;
43         scanf( "%d%d" , &_x , &_y ) ;
44         wat[ _x ][ _y ] = true ;
45     }
46     for(int i=1 ; i<=N ; ++i )
47         for(int j=1 ; j<=M ; ++j )
48             if((i % 2 && j % 2) || (i%2==0 && j%2==0))map[ i][ j ] = 1 ;
49     for(int i=1 ; i<=N ; ++i )
50     {
51         for(int j=1 ; j<=M ; ++j )
52         {
53             if( !wat[ i ][ j ] && map[ i ][ j ] )
54             {
55                 memset ( used, 0 , sizeof ( used ) ) ;
56                 if ( find ( i , j ) ) ans++ ;
57             }
58         }
59     }
60     printf( "%d" , ans ) ;
61     return 0 ;
62 }

2016-09-16 15:46:24

 

(完)

原文地址:https://www.cnblogs.com/shadowland/p/5876554.html