Codevs1022 覆盖——匈牙利算法

题目描述 Description

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

img

输入描述 Input Description

输入文件的第一行是两个整数N*M* (1<=N,**M<=*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
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#define INF 1e+9
#define maxn 101
using namespace std;
int mc[maxn][maxn][2],tot;
bool vis[maxn][maxn];
int N,M;
int map1[maxn][maxn];
int wat[maxn][maxn];
int Next[4][2] = {0,1,0,-1,1,0,-1,0};
bool find(int x,int y){
    int nx,ny;
    for(int k=0;k<4;k++){
        nx = x+Next[k][0];
        ny = y+Next[k][1];
        if(nx>=1 && ny>=1 && nx<=N && ny<=M){
            if(!wat[nx][ny] && !vis[nx][ny] && !map1[nx][ny]){
                vis[nx][ny] = true;
                if(!mc[nx][ny][0] || find(mc[nx][ny][0],mc[nx][ny][1])){
                    mc[nx][ny][0] = x;
                    mc[nx][ny][1] = y;
                    return true;
                }
            }
        }
    }
    return false;
}
int getAnswer(){
    int ans = 0;
    for(int i=1;i<=N;i++){
        for(int j=1;j<=M;j++){
            // 不是水塘且为1
            if(!wat[i][j] && map1[i][j]){
                memset(vis,0,sizeof vis);
                if(find(i,j))
                    ++ans;
            }
        }
    }
    return ans;
}

int main(){
    cin>>N>>M;
    int K,X,Y;
    cin>>K;
    for(int i=1;i<=K;i++){
        scanf("%d%d",&X,&Y);
        wat[X][Y] = 1; //图中为1的位置是水塘
    }
    for(int i=1; i<=N; i++)
        for(int j=1; j<=M; j++)
            if((i%2 && j%2) || (i%2==0 && j%2==0))
                map1[i][j]=1;//将地图分为0,1
    cout<<getAnswer()<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhaohaibo_/article/details/81455985