zoukankan      html  css  js  c++  java
  • poj2226 二分图匹配

    在一块 n imes mn×m 的地面上,有一些格子是泥泞的,有一些格子是干净的。现在需要用一些宽度为 11 、长度任意的木板把泥地盖住,同时不能盖住干净的地面,木板可以重叠。求最少需要多少块木板。 n,m leq 50n,m50 。

    22 要素:每块泥地要么被横着的木板盖住,要么被竖着的木板盖住。

    横着的木板只能放在同一行若干个连续的泥地上,称这种连续的泥地为行泥泞块;竖着的木板只能放在同一列若干个连续的泥地上,称这种连续的泥地为列泥泞块。

    把行泥泞块作为左部节点,列泥泞块作为右部节点。对于每块泥地,在其对应的行泥泞块和列泥泞块之间连边。

    求出这张二分图的最小覆盖即可。

     注意  这题和那个棋盘车的题目不一样!!!行列建图显然是错的

    要特殊的以横板为左图  竖版为右图来建图!

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    
    using namespace std;
    const int N = 55;
    const int M = N*N;
    char a[N][N];
    int row[N][N],col[N][N];
    int R,C;
    bool vis[M];
    int linker[M];
    int to[M],nxt[M];
    int head[M],tot;
    int n, m;
    
    void addedge(int u, int v)
    {
        ++tot;
        to[tot] = v;
        nxt[tot] = head[u];
        head[u] = tot;
    }
    
    bool dfs(int u)
    {
        for(int i = head[u]; ~i; i = nxt[i])
        {
            int v = to[i];
            if(!vis[v])
            {
                vis[v] = 1;
                if(linker[v]==-1 || dfs(linker[v]))
                {
                    linker[v] = u;
                    return 1;
                }
            }
        }
        return 0;
    }
    
    int hungary()
    {
        int ret = 0;
        memset(linker, -1, sizeof(linker));
        for(int i = 1; i <= R; ++i)
        {
            memset(vis, 0, sizeof(vis));
            if(dfs(i))
                ++ret;
        }
        return ret;
    }
    
    int main()
    {
        while(~scanf("%d %d", &n, &m))
        {
            memset(row, 0, sizeof(row));
            memset(col, 0, sizeof(col));
            memset(head, -1, sizeof(head));
            tot = -1;
            R = C = 0;
            for(int i = 1; i <= n; ++i)
                for(int j = 1; j <= m; ++j)
                {
                    cin >> a[i][j];
                    if(a[i][j]=='*')
                    {
                        if(row[i][j-1]) row[i][j] = row[i][j-1];
                        else row[i][j] = ++R;
                        if(col[i-1][j]) col[i][j] = col[i-1][j];
                        else col[i][j] = ++C;
                    }
                }
            for(int i = 1; i <= n; ++i)
                for(int j = 1; j <= m; ++j)
                    if(a[i][j]=='*')
                        addedge(row[i][j], col[i][j]);
            printf("%d
    ", hungary());
        }
        return 0;
    }
    View Code
  • 相关阅读:
    8.26 树状数组
    8.27 神异之旅
    8.26 雇佣
    8.28 Jack与Rose
    8.28 ISN
    保存和加载网络
    快速搭建网络
    分类网络
    torch中的回归
    pytorch中的Variable
  • 原文地址:https://www.cnblogs.com/bxd123/p/10932872.html
Copyright © 2011-2022 走看看