zoukankan      html  css  js  c++  java
  • poj 2446 二分图最大匹配

    题意:给一张m*n的棋盘,上面有k个格子有洞,用1*2的骨牌将棋盘覆盖,每个格子必须被恰好覆盖一次,有洞的地方不能覆盖,问是否存在这样的方案。

    思路:容易想到将格点作为二分图中的点,骨牌作为二分图中的边(骨牌可能放置时),求二分图的最大匹配,如果匹配数与n*m-k相等,则方案存在,否则不存在;容易想到当n*m-k为奇数时方案一定不存在;

    构思时的难点在于将格点用一维坐标表示出来,后来发现是自己傻逼了.....标号就可以解决问题。

    坑点:读入洞的坐标时列号在前,行号在后。

    不算坑点的坑点:题目有多组case。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 
     6 const int maxn = 50;
     7 bool g[maxn*maxn][maxn*maxn];
     8 int link[maxn*maxn];
     9 bool check[maxn*maxn];
    10 int maze[maxn][maxn];
    11 
    12 int n,m,cnt;
    13 int dir[4][2] = {{1,0},{-1,0},{0,-1},{0,1}};
    14 
    15 bool dfs(int u){
    16     for(int i = 1; i <= cnt; ++i){
    17         if(!check[i] && g[u][i]){
    18             check[i] = true;
    19             if(link[i] == -1 || dfs(link[i])){
    20                 link[i] = u;
    21                 return true;
    22             }
    23         }
    24     }
    25     return false;
    26 }
    27 
    28 int hungarian(){
    29     int ans = 0;
    30     memset(link,-1,sizeof(link));
    31     for(int i = 1; i <= cnt; ++i){
    32         memset(check,0,sizeof(check));
    33         if(dfs(i)) ++ans;
    34     }
    35     return ans;
    36 }
    37 
    38 int main(){
    39    int k;
    40    while(scanf("%d%d%d",&m,&n,&k) == 3){
    41        memset(maze,0,sizeof(maze));
    42        memset(g,0,sizeof(g));
    43        cnt = 0;
    44        int x,y;
    45        for(int p = 0; p < k; ++p){
    46             scanf("%d%d",&x,&y);
    47             maze[y][x] = -1;
    48        }
    49        if((n*m-k) & 1){
    50            printf("NO
    ");
    51            continue;
    52        }
    53        for(int i = 1; i <= m; ++i){
    54            for(int j = 1; j <= n; ++j){
    55               if(maze[i][j] == 0){
    56                    maze[i][j] = ++cnt;
    57               }
    58            }
    59        }
    60        for(int i = 1; i <= m; ++i){
    61            for(int j = 1; j <= n; ++j){
    62               if(maze[i][j] > 0){
    63                    for(int p = 0; p < 4; ++p){
    64                         int nx = i + dir[p][0], ny = j + dir[p][1];
    65                         if(nx >= 1 && nx <= m && ny >= 1 && ny <= n){
    66                             g[maze[i][j]][maze[nx][ny]] = 1;
    67                         }
    68                    }
    69               }
    70            }
    71        }
    72        int res = hungarian();
    73        if(res + k == n*m) printf("YES
    ");
    74        else printf("NO
    ");
    75    }
    76    return 0;
    77 }
  • 相关阅读:
    mysql json 嵌套数组查询
    Centos 部署 mysql
    Mysql8.0 导出数据库文档
    MySQL常用Json函数
    java Dateutil 操作类
    雪花算法生成的ID,前端无法使用
    Mysql 一个字段匹配多个字符
    EntityManager 获取 List<T>
    高级软件工程第二次作业:随机生成N个不重复的已解答完毕的数独棋盘
    调研《构建之法》指导下的全国高校优秀实践作品三篇
  • 原文地址:https://www.cnblogs.com/Pos-Proteus/p/5781795.html
Copyright © 2011-2022 走看看