zoukankan      html  css  js  c++  java
  • U64949 棋盘覆盖(二分图)| 二分图匹配总结

    https://ac.nowcoder.com/acm/contest/1062/B

    【题目】

    给出一张n×n(n≤100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少1*2的多米诺骨牌进行掩盖。

    【题意】

    题意简单,不做多说明,多米诺骨牌可以理解为长方形的方块。

    【题解】

    仔细一想,可以发现能用二分图来做。即可以把每个位置的点进行重新编号,相邻的两点具有不同的性质。

    比如说在2×2的图内第一个点((1,1))标记为1,它是奇数,那么与它相邻的((1,2)(1,2))就要标记成偶数。又比如在3×3的图内的点((2,2))为奇数,那么((1,2),(2,1)(2,3),(3,2))的点就要标记为偶数。然后两两建边,奇数点->偶数点 or 偶数点->奇数点(当然如果是被删除的点,则不能建边)。最后对 偶数点 or 奇数点 跟 奇数点 or 偶数点 进行二分图匹配即可。

    时间复杂度:(O(N^2M^2))

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 110;
    const int dx[] = { 0,1,0,-1 };
    const int dy[] = { 1,0,-1,0 };
    int n, m, ans, f[N * N];
    bool b[N][N], v[N * N];
    vector<int>e[N * N];
    
    bool dfs(int x) {
        for (unsigned int i = 0; i < e[x].size(); i++) {
            int y = e[x][i];
            if (v[y]) continue;
            v[y] = 1;
            if (f[y] == -1 || dfs(f[y])) {
                f[y] = x;return 1;
            }
        }
        return 0;
    }
    
    int main() {
        //freopen("in.txt", "r", stdin);
        ios::sync_with_stdio(false), cin.tie(0);
        cin >> n >> m;
        while (m--) {
            int x, y; cin >> x >> y;
            b[x - 1][y - 1] = 1;
        }
        for (int i = 0; i < n; i++)
    		for (int j = 0; j < n; j++)
    			if (!b[i][j])
    				for (int k = 0; k < 4; k++) {
    					int x = i + dx[k], y = j + dy[k];
    					if (x >= 0 && x < n && y >= 0 && y < n && !b[x][y]) {
    						e[i*n+j].push_back(x * n + y);
    						e[x*n+y].push_back(i * n + j);
    					}
    				}
        memset(f, -1, sizeof(f));
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++) {
                if ((i ^ j) & 1) continue;
                memset(v, 0, sizeof(v));
                ans += dfs(i * n + j);
            }
        cout << ans << endl;
    }
    

    题后总结:

    二分图匹配的模型有两个要素

    1. 节点能分成两个集合,每个集合内部有0条边。
    2. 每个节点只能与 1 条边相连。

    我们简单把它称为 ”0要素“ 和 ”1要素“ 。在把实际问题抽象成二分图匹配时,我们就要寻找题目中具有这种 ”0“ 和 ”1“ 性质的对象从而发现构建模型的突破口。

  • 相关阅读:
    CSS 3中细线边框如何实现?
    【SPL标准库专题(1)】 SPL简介
    【PSR规范专题(5)】PSR-4 改进后的自动加载规范
    【PSR规范专题(4)】PSR-3 日志接口规范
    【PSR规范专题(3)】PSR-2 代码风格规范
    【PSR规范专题(2)】PSR-1 基本代码规范
    YII框架的依赖注入容器与服务定位器简述
    PHP 反射机制Reflection
    【Apache运维基础(5)】Apache的Rewrite攻略(2)
    【Apache运维基础(4)】Apache的Rewrite攻略(1)
  • 原文地址:https://www.cnblogs.com/RioTian/p/13475960.html
Copyright © 2011-2022 走看看