POJ2226 Muddy Fields 二分图求最小覆盖点

来源:互联网 发布:达梦数据库公司上市 编辑:程序博客网 时间:2024/04/29 09:20
  这题的关键在于建图,这题当中,因为要求木板覆盖泥坑,但又不能覆盖草,所以不能简单的行和列对应建图,我们要对行中泥坑进行编号,连一起的编同样的号,同样的对列中连一起的泥坑进行编号,如果行列编号的一块泥坑连一起,便为这两个编号建立边,这样对其进行匈牙利算法求最大匹配,就是最小覆盖点,就是答案。
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#define maxn 505#define mem(a) memset(a, 0, sizeof(a))using namespace std;char maps[maxn][maxn];bool map[maxn][maxn], vis[maxn];int lk[maxn], numw[maxn][maxn], n, m, w, h;bool dfs(int a){int i;for(i = 0;i <= h;i++){if(!vis[i]&&map[a][i]){vis[i] = 1;if(lk[i] == -1||dfs(lk[i])){lk[i] = a;return true;}}}return false;}int res(){int i;int ress = 0;memset(lk, -1, sizeof(lk));for(i = 0;i <= w;i++){mem(vis);        if(dfs(i))        ress++;}return ress;}int main(int argc, char *argv[]){    int eagenum, i, j, ans;    while(scanf("%d%d%*c", &n, &m) != EOF)    {    mem(map);    mem(maps);    w = -1;    h = -1;    for(i = 0;i < n;i++)    {    for(j = 0;j < m;j++)    {    scanf("%c", &maps[i][j]);    }    scanf("%*c");    }    for(i = 0;i < n;i++)    {    for(j = 0;j < m;j++)    {    if(j == 0&&maps[i][j] == '*')    numw[i][j] = ++w;    else if(maps[i][j] == '*'&&maps[i][j - 1] == '*')    numw[i][j] = w;    else if(maps[i][j] == '*'&&maps[i][j - 1] != '*')    numw[i][j] = ++w;    }    }    for(i = 0;i < m;i++)    {    for(j = 0;j < n;j++)    {    if(j == 0&&maps[j][i] == '*')    map[numw[j][i]][++h] = 1;    else if(maps[j][i] == '*'&&maps[j - 1][i] == '*')    map[numw[j][i]][h] = 1;    else if(maps[j][i] == '*'&&maps[j - 1][i] != '*')    map[numw[j][i]][++h] = 1;    }    }    ans = res();    printf("%d\n", ans);    }return 0;}

0 0
原创粉丝点击