• 匈牙利算法实战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;
    
    }
  • 相关阅读:
    has already been called for this response
    Mysql Innodb的两种表空间方式
    针对MyISAM表锁的解决方案
    MySQL数据库表修复--MyISAM
    如何修复损坏的MySQL数据表[转]
    MySQL大量unauthenticated user
    Linux基本命令篇 进程管理
    Linux 知识点滴
    Linux基本命令篇 用户管理
    Linux基本命令篇 文件管理
  • 原文地址:https://www.cnblogs.com/DWVictor/p/10283046.html
Copyright © 2020-2023  润新知