Chessboard poj2446 匈牙利匹配 + 图建模棋盘染色

思路:给你一个n * m的棋盘,有hole。问能否在不遮住hole的情况下,将棋盘全部用1 * 2的矩形覆盖。
分析图形,使用匈牙利匹配奇数坐标和偶数坐标,看是否能完全匹配即可。

#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
int vis[2500], vis1[500][500], vis2[500][500], vis3[500][500], Link[2500], g[200][200];
vector<int>G[2005];
int n, m, sum;
bool Find(int u)
{
    for(int i = 0; i < G[u].size(); i++)
    {
        int t = G[u][i];
        if(!vis[t])
        {
            vis[t] = 1;
            if( Link[t] == -1 || Find(Link[t]))
            {
                Link[t] = u;
                return true;
            }
        }
    }
    return false;
}
int solve()
{
    int cnt = 0;
    memset(Link, -1, sizeof Link);
    for(int i = 1; i <= sum; i++)
    {
        memset(vis, 0, sizeof vis);
        if(G[i].size())
        {
            if(Find(i))
                cnt++;
        }
    }
    return cnt;
}
int main()
{
    int h;
    while(cin >> n >> m >> h)
    {
        memset(g, 0, sizeof g);
        memset(vis1, 0, sizeof vis1);
        memset(vis2, 0, sizeof vis2);
        memset(vis3, 0, sizeof vis3);
        for(int i = 1; i <= h; i++)
        {
            int x, y;
            cin >> x >> y;
            g[y][x] = 1;
        }
        sum = 0;
        int cnt1 = 0, cnt2 = 0;
        for(int i = 1; i <= n; i++)
            for(int j = 1; j  <= m; j++)
            {
                vis2[i][j] = ++sum;
                if(g[i][j] == 0)
                {
                    if((i + j) % 2 == 0)
                        cnt1++;
                    else cnt2++;
                }
            }
        int T = 2;
        int flag = 0;
        while(T--)
        {
             memset(vis3, 0, sizeof vis3);
            for(int i = 1; i <= n; i++)
                for(int j = 1; j <= m; j++)
                    if(vis3[i][j] == 0 && g[i][j] == 0 && ((i + j )% 2 == T))
                    {
                        if(g[i + 1][j] == 0 && i + 1 <= n)
                        {
                            G[vis2[i][j]].push_back(vis2[i + 1][j]);
                            vis3[i + 1][j] = 1;
                        }
                        if(g[i - 1][j] == 0 && i - 1 >= 1)
                        {
                            G[vis2[i][j]].push_back(vis2[i - 1][j]);
                            vis3[i - 1][j] = 1;
                        }
                        if(g[i][j + 1] == 0 && j + 1 <= m)
                        {
                            G[vis2[i][j]].push_back(vis2[i][j + 1]);
                            vis3[i][j + 1] = 1;
                        }
                        if(g[i][j - 1] == 0 && j - 1 >= 1)
                        {
                            G[vis2[i][j]].push_back(vis2[i][j - 1]);
                            vis3[i][j - 1] = 1;
                        }
                    }
            int t = solve();
            //cout << t << endl;
            if(2 * t == (n * m - h) && (n * m - h) % 2 == 0 && cnt1 == cnt2)
            flag = 1;
             for(int i = 1; i <= sum; i++)
            {
                G[i].clear();
            }
        }
        if(flag)cout << "YES" << endl;
        else cout << "NO" << endl;
    }
    return 0;
}

发布了241 篇原创文章 · 获赞 8 · 访问量 4813

猜你喜欢

转载自blog.csdn.net/weixin_43960370/article/details/104079602