POJ - 2446 Chessboard 二分图 最大匹配(输入坑)

题目大意:有一个n*m的棋盘,棋盘上面有k个洞。

现在要求你在这棋盘上面放1*2的矩形,使得棋盘上除k个洞之外的所有点都被1 * 2的矩形覆盖,且只覆盖一次

解题思路:思路不难想到,将每一点作为两个点集(除洞之外),点集之间的联系表示该点能联通的点,这样二分图就构造完成了

只需要求出最大匹配数,再和n * m -k比较即可

输入是个坑啊,输入的坐标是(x,y),但是表示的缺失y行,x列

#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int N = 1100;
const int M = 35;
int g[M][M], vis[N], link[N], x[N], y[N];
int n, m, k;
vector<int> point[N];

void init() {
    for(int i = 0; i < k; i++)
        scanf("%d%d", &x[i], &y[i]);

    if((n * m - k) % 2)
        return ;
    for(int i = 1; i <= n * m; i++)
        point[i].clear();
    memset(g, 0, sizeof(g));
    for(int i = 0; i < k; i++)
        g[y[i]][x[i]] = 1;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++) {
            if(i - 1 > 0 && !g[i-1][j])
                point[i * n + j].push_back((i - 1) * n + j);

            if(i + 1 <= n && !g[i+1][j])
                point[i * n + j].push_back((i + 1) * n + j);

            if(j - 1 > 0 && !g[i][j-1])
                point[i * n + j].push_back(i * n + j - 1);

            if(j + 1 <= m && !g[i][j+1])
                point[i * n + j].push_back(i * n + j + 1);
        }
    memset(link, 0, sizeof(link));
}

bool dfs(int u) {
    for(int i = 0; i < point[u].size(); i++) {
        int v = point[u][i];
        if(vis[v])
            continue;
        vis[v] = 1;
        if(!link[v] || dfs(link[v])) {
            link[v] = u;
            return true;
        }
    }
    return false;
}

void hungary() {
    int ans = 0;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++) {
            if(!g[i][j]) {
                memset(vis, 0, sizeof(vis));
                if(dfs(i * n + j))
                    ans++;
            }
        }
    if(ans == n * m - k)
        printf("YES\n");
    else
        printf("NO\n");

}

int main() {
    while(scanf("%d%d%d", &n, &m, &k) != EOF) {
        init();
        if((n * m - k) % 2) {
            printf("NO\n");
            continue;
        }
        hungary();
    }
    return 0;
}
时间: 2024-10-05 16:47:58

POJ - 2446 Chessboard 二分图 最大匹配(输入坑)的相关文章

POJ 2446 Chessboard (二分图最大匹配)

题目链接:http://poj.org/problem?id=2446 给你一个n*m的棋盘,其中有k个洞,现在有1*2大小的纸片,纸片不能覆盖洞,并且每个格子最多只能被覆盖一次.问你除了洞口之外这个棋盘是否能被纸片填满. 这个题目一眼很难看出是二分图匹配... 可以根据i和j性质可以看出,i+j为奇数的上下相邻的i'和j'一定是偶数,那么一个1*2的纸片的i+j一定是一个奇数一个偶数.所以我是建立一个二分图两个集合,将i+j为奇数的点与上下左右相邻的点连在一起,当然点不是洞.最后就用匈牙利算法

poj 2446 Chessboard (二分图利用奇偶性匹配)

Chessboard Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13176   Accepted: 4118 Description Alice and Bob often play games on chessboard. One day, Alice draws a board with size M * N. She wants Bob to use a lot of cards with size 1 * 2

POJ 1469 COURSES 二分图最大匹配

就是判断一下是不是每一个课程都能找到自己的代表人,做一遍最大匹配看看匹配数是否等于p即可 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cs

POJ 2446 Chessboard(二分图最大匹配)

题意: M*N的棋盘,规定其中有K个格子不能放任何东西.(即不能被覆盖) 每一张牌的形状都是1*2,问这个棋盘能否被牌完全覆盖(K个格子除外) 思路: M.N很小,把每一个可以覆盖的格子都离散成一个个点,然后二分图最大匹配. 一个重要的问题**:可不可能存在建完的图是这样的情况:1-2,2-3,3-4,4-5,5-1?这种情况二分图最大匹配是5,但实际上答案是不对的. 证明:不可能存在这样的由奇个点构成的环图.我们按这种方法来看看能不能构造出这样一个棋盘. 假设有2k+1个个格(奇数),则第k+

【网络流#6】POJ 3041 Asteroids 二分图最大匹配 - 《挑战程序设计竞赛》例题

学习网络流中ing...作为初学者练习是不可少的~~~构图方法因为书上很详细了,所以就简单说一说 把光束作为图的顶点,小行星当做连接顶点的边,建图,由于 最小顶点覆盖 等于 二分图最大匹配 ,因此求二分图最大匹配即可. 邻接矩阵,DFS寻找增广路,匈牙利算法 邻接矩阵:复杂度O(n^3) 如果使用邻接表:复杂度O(n*m) #include<cstdio> #include<cstring> #include<cmath> #include<iostream>

POJ 1469 COURSES (二分图最大匹配 匈牙利算法)

COURSES Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18892   Accepted: 7455 Description Consider a group of N students and P courses. Each student visits zero, one or more than one courses. Your task is to determine whether it is poss

poj - 3041 Asteroids (二分图最大匹配+匈牙利算法)

http://poj.org/problem?id=3041 在n*n的网格中有K颗小行星,小行星i的位置是(Ri,Ci),现在有一个强有力的武器能够用一发光速将一整行或一整列的小行星轰为灰烬,想要利用这个武器摧毁所有的小行星最少需要几发光束. 主要是构图,将每一行当成一个点,构成集合1,每一列也当成一个点,构成集合2,每一个障碍物的位置坐标将集合1和集合2的点连接起来,也就是将每一个障碍物作为连接节点的边,这样可以得出本题是一个最小点覆盖的问题==二分图的最大匹配. 就可以通过匈牙利算法求解.

poj 2446 Chessboard (二分匹配)

Chessboard Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12800   Accepted: 4000 Description Alice and Bob often play games on chessboard. One day, Alice draws a board with size M * N. She wants Bob to use a lot of cards with size 1 * 2

POJ 2446 Chessboard

要求用占两格的长方形铺满平面上除去指定点 二分图匹配 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int dx[]={1,-1,0,0}; 6 int dy[]={0,0,1,-1}; 7 int map[40][40]; 8 int vis[40][40]; 9 int link[40*40]; 10 int m,n,k; 11 bool