• POJ2226(二分图建图/最小点覆盖)


    题意:
    给定m*n的棋盘,有若干只咕咕。希望去掉一部分咕咕使得剩下的咕咕在上下左右四个方向越过咕咕槽的情况下都看不到咕咕。
    思路:
    建立一个二分图的方法有很多,这里采用xy二分。
    假设没有咕咕槽的情况下,咕咕的最大放置数其实有点像八皇后问题,当然这里我们用最大匹配的思路求解。
    当一个位置上放置了咕咕,那么其坐标(x,y)便被移除了待选集合,由此可见,如果建立一个X和Y的二分图,那么最大咕咕数就是二分图的最大匹配。
    有锅的时候,相比于没有锅的时候难度增加在了怎么建边上,我们仍然想通过编号的方式建边,那么对于每个横向、竖向区域便可以可以用他们最左边最右边的区域的编号代替,将其建边求最大二分匹配即可。(说见了就是锅的右边行+1,锅的下边列+1)。

    //https://blog.csdn.net/sotifish/article/details/48396087
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    using namespace std;
    const int maxn = 10005;
    vector<int> G[maxn];
    char s[maxn][maxn];
    bool vis[maxn];
    int match[maxn];
    int n, m;
    
    void add_edge(int u, int v) {
        G[u].push_back(v);
        G[v].push_back(u);
    }
    
    bool dfs(int u) {
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i];
            if (!vis[v]) {
                vis[v] = true;
                if (match[v] < 0 || dfs(match[v])) {
                    match[v] = u;
                    return true;
                }
            }
        }
        return false;
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        memset(match, -1, sizeof(match));
        for (int i = 0; i < n; i++) {
            scanf("%s", s[i]);
        }
        int cnt = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] == 'o') {
                    int x = i, y = j;
                    while (x > 0 && s[x - 1][j] != '+') x--;
                    while (y > 0 && s[i][y - 1] != '+') y--;
                    add_edge(x*m + j, i*m + y + m*n);
                    if (s[i][j] == 'o')cnt++;
                }
            }
        }
        int res = 0, num;
        for (int i = 0; i < n*m; i++)
        {
            memset(vis, false, sizeof(vis));
            if (dfs(i)) res++;
        }
        if (cnt <= res || cnt == 0) num = 0;
        else num = cnt - res;
        printf("%d
    ", num);
        return 0;
    }
  • 相关阅读:
    异步解决方案
    踩过的坑:InteliIJ IDEA 打开的项目突然左侧目录结构消失了,如何处理?
    了解Katalon的安装及基本使用(for mac)
    GitLab如何创建分支及拉取代码
    mocha测试接口类型及测试报告收集
    linux下sourcetree回退已推送的代码
    nodejs开篇基础<①>
    nodejs运行的两种方式<小记>
    Django视图函数之FBV与CBV模式
    Django之views.py视图函数学习
  • 原文地址:https://www.cnblogs.com/romaLzhih/p/9489836.html
Copyright © 2020-2023  润新知