匈牙利算法实战codevs1022覆盖

Posted dwvictor

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了匈牙利算法实战codevs1022覆盖相关的知识,希望对你有一定的参考价值。

 1022 覆盖

 
 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 大师 Master
 
 
题目描述 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






解题思路   将该题目转化为二分图使用匈牙利算法解

n*m的格子可以按顺序分成0 1的图
如 
0101010101
1010101010
0101010101
1010101010
一个点的位置(x,y)可以和周围的点(x+1,y),(x,y-1),(x,y+1),(x-1,y)进行两两匹配
有水的地方直接跳过
得出最后最多有多少对匹配成功的点
即答案所求 多少可以覆盖多少板子


#include<iostream>

#include<cstring>

using namespace std;

int n,m,k,a,b,ans;

bool water[101][101];

bool ok[101][101];

int linkx[101][101];

int linky[101][101];

int dx[]={0,0,1,-1};

int dy[]={1,-1,0,0};

bool dfs(int x,int y)

{

    if(water[x][y])return false;

    for(int i=0;i<4;i++)

    {

        int xx=x+dx[i];

        int yy=y+dy[i];

        if(xx>0&&yy>0&&yy<=m&&xx<=n&&water[xx][yy]==false&&ok[xx][yy]==false)

        {

            ok[xx][yy]=true;

            if(linkx[xx][yy]==0||dfs(linkx[xx][yy],linky[xx][yy]))

            {

                linkx[xx][yy]=x;

                linky[xx][yy]=y;

                return true;

            }

        }

    }

    return false;

}

int main()

{

    cin>>n>>m>>k;

    for(int i=0;i<k;i++)

    {

        cin>>a>>b;

        water[a][b]=true;

    }

    for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)

       {

        memset(ok,0,sizeof(ok));

        if(i%2==j%2)

         if(dfs(i,j))

            ans++;

       }

       cout<<ans<<endl;

    return 0;

}

 

以上是关于匈牙利算法实战codevs1022覆盖的主要内容,如果未能解决你的问题,请参考以下文章

codevs 1022 覆盖

CODEVS1022 覆盖

匈牙利算法(codevs2776)

矩阵游戏|ZJOI2007|BZOJ1059|codevs1433|luoguP1129|二分图匹配|匈牙利算法|Elena

[POJ3041] Asteroids(最小点覆盖-匈牙利算法)

POJ 3041 Asteroids(二分图 && 匈牙利算法 && 最小点覆盖)