zoukankan      html  css  js  c++  java
  • POJ

    题意:

      给出一个图, * 代表泥地, . 代表草地。用尽量少的木板盖住泥地,木板可以盖住任意长度的行或列,木板可以重叠但是不能盖住草地。求最少的木板数量。

    题解:

      这道题有点像POJ3041的变形。在那道题之上把连着的行或列编上号,相连即可。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    using namespace std;
    const int maxn = 3000;
    int r, c;
    int cnt;
    int map[55][55];
    char s[55][55];
    int vis[maxn];
    int match[maxn];
    vector<int> g[maxn];
    void add_edge(int u, int v) {
        g[u].push_back(v);
        g[v].push_back(u);
    }
    bool dfs(int u) {
        vis[u] = 1;
        for(int i = 0; i < g[u].size(); i++) {
            int v = g[u][i], w=match[v];
            if(w<0 || !vis[w] && dfs(w)) {
                match[v] = u;
                match[u] = v;
                return true;
            }
        }
        return false;
    }
    int hungarian() {
        int res = 0;
        memset(match, -1, sizeof(match));
        for(int u = 1; u <= cnt; u++) {
            if(match[u] < 0) {
                memset(vis, 0, sizeof(vis));
                if(dfs(u)) res++;
            }
        }
        return res;
    }
    int main() {
        scanf("%d%d", &r, &c);
        for(int i = 0; i < r; i++) scanf("%s", s[i]);
        for(int i = 0; i < r; i++) {
            int flag = 0;
            for(int j = 0; j < c; j++) {
                if(flag==1 && s[i][j]=='*') map[i][j] = cnt;
                if(flag==0 && s[i][j]=='*') {
                    flag = 1;
                    map[i][j] = ++cnt;
                }
                if(s[i][j] == '.') flag = 0;
            }
        }
        for(int i = 0; i < c; i++) {
            int flag = 0;
            for(int j = 0; j < r; j++) {
                if(flag==1 && s[j][i]=='*') add_edge(cnt, map[j][i]);
                if(flag==0 && s[j][i]=='*') {
                    flag = 1;
                    cnt++;
                    add_edge(cnt, map[j][i]);
                }
                if(s[j][i] == '.') flag = 0;
            }
        }
        printf("%d
    ", hungarian());
    }
    View Code
  • 相关阅读:
    写日志文件
    内存文件映射应用举例『转』
    HOOK编程
    获取当前进程的名称
    C++实现FTP文件传输
    C/C++ 实现windows进程/线程/模块 遍历
    Unicode下的CString与char *转换
    MFC常用基本数据类型
    geos 3.6.1编译 win7 vs2015
    JQuery Mobile iscroll插件使用教程及注意事项
  • 原文地址:https://www.cnblogs.com/Pneuis/p/8698443.html
Copyright © 2011-2022 走看看