poj2226 二分图匹配

在一块 n \times 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\n", hungary());
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/bxd123/p/10932872.html