• POJ-2446-Chessboard(二分图匹配)


    链接:https://vjudge.net/problem/POJ-2446#author=0

    题意:

    有一天,罗老板画了一块尺寸为M * N的棋盘。他希望许老师能够使用1 * 2的牌来覆盖棋盘。然而,他认为这很容易,所以他增大了难度,他在棋盘上打了一些洞 

    许老师必须遵守以下规则: 
    1.任何不是洞网格都应该只被一张卡覆盖。 
    2. 一张卡应该正好覆盖2个相邻非洞网格。 
    3. 洞不可以被卡片覆盖

    你的任务是帮助许老师确定 根据上述规则 是否存在一种方案可以覆盖棋盘

    思路:

    二分图匹配.因为一个1*2的方块,所放的两个格子,一个格子的x+y是偶数,一个是奇数,所以可以以x+y根据奇偶建图,再去求二分图。

    代码:

    #include <iostream>
    #include <memory.h>
    #include <string>
    #include <istream>
    #include <sstream>
    #include <vector>
    #include <stack>
    #include <algorithm>
    #include <map>
    #include <queue>
    #include <math.h>
    #include <cstdio>
    #include <set>
    #include <iterator>
    #include <cstring>
    using namespace std;
    
    typedef long long LL;
    const int MAXN = 2000;
    int Next[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    
    int Dis[40][40];
    int G[MAXN][MAXN];
    int Link[MAXN];
    bool Used[MAXN];
    int n, m, k;
    int cnt1, cnt2;
    
    bool Dfs(int x)
    {
        for (int node = 1;node <= cnt2;node++)
        {
            if (G[x][node] == 1 && Used[node] == false)
            {
                Used[node] = true;
                if (Link[node] == -1 || Dfs(Link[node]))
                {
                    Link[node] = x;
                    return true;
                }
            }
        }
        return false;
    }
    
    int Solve()
    {
        int res = 0;
        memset(Link, -1, sizeof(Link));
        for (int i = 1;i <= cnt1;i++)
        {
            memset(Used, 0, sizeof(Used));
            if (Dfs(i))
                res++;
        }
        return res;
    }
    
    int main()
    {
        while (cin >> n >> m >> k)
        {
            memset(Dis, 0, sizeof(Dis));
            int y, x;
            for (int i = 1;i <= k;i++)
            {
                cin >> y >> x;
                Dis[x][y] = -1;
            }
            cnt1 = cnt2 = 0;
            for (int i = 1;i <= n;i++)
            {
                for (int j = 1;j <= m;j++)
                {
                    if (Dis[i][j] != -1)
                    {
                        if ((i+j)%2 == 0)
                            Dis[i][j] = ++cnt1;
                        else
                            Dis[i][j] = ++cnt2;
                    }
                }
            }
            for (int i = 1;i <= n;i++)
            {
                for (int j = 1;j <= m;j++)
                {
                    if (Dis[i][j] != -1 && (i+j)%2 == 0)
                    {
                        for (int k = 0;k < 4;k++)
                        {
                            int tx = i+Next[k][0];
                            int ty = j+Next[k][1];
                            if (tx < 1 || tx > n || ty < 1 || ty > m)
                                continue;
                            G[Dis[i][j]][Dis[tx][ty]] = 1;
                        }
                    }
                }
            }
            if ((n*m-k)%2 == 1 || cnt1 != cnt2)
            {
                cout << "NO" << endl;
                continue;
            }
            int res = Solve();
            if (res == (n*m-k)/2)
                cout << "YES" << endl;
            else
                cout << "NO" << endl;
        }
    
        return 0;
    }
    

      

  • 相关阅读:
    聚焦WCF行为的扩展
    软件设计经典书籍推荐
    善变者常新
    开发WCF/Silverlight须知
    面向对象设计讲义
    站立会议变形记
    敏捷开发思想之拥抱变化
    WCF 4.0中的WSDiscovery
    QCon日记
    创投“黑帮”,必须的
  • 原文地址:https://www.cnblogs.com/YDDDD/p/10859069.html
Copyright © 2020-2023  润新知