您的位置:首页 > 其它

poj 2226 Muddy Fields 最小点覆盖

2011-02-10 12:06 387 查看
转换成求最小点覆盖数

构图方式如下:横行的连续*方块作为X集合里的顶点,纵行的连续*方块作为Y集合的顶点,若两个方块相交,则用边把这两个顶点相连。然后求最小点覆盖数(求最大匹配),即为答案。

要注意构图后的顶点数。

#include <iostream>
#include <cstring>
using namespace std;

const int N = 55;
const int MAX = N*N;

struct Xblock
{
int x;
int sty, edy;
};

struct Yblock
{
int y;
int stx, edx;
};

Xblock xblock[MAX];
Yblock yblock[MAX];
bool maze[MAX][MAX];
char map

;
bool isvisit[MAX];
int match[MAX];

int cnt_x, cnt_y;
int row, col;

void build_graph()
{
cnt_x = 0;
cnt_y = 0;

for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
{
if (map[i][j] == '*')
{
xblock[cnt_x].x = i;
xblock[cnt_x].sty = j;
while (j < col && map[i][j] == '*')
{
xblock[cnt_x].edy = j;
j++;
}
cnt_x++;
}
}

for (int j = 0; j < col; j++)
for (int i = 0; i < row; i++)
{
if (map[i][j] == '*')
{
yblock[cnt_y].y = j;
yblock[cnt_y].stx = i;

while (i < row && map[i][j] == '*')
{
yblock[cnt_y].edx = i;
i++;
}
cnt_y++;
}
}

memset(maze, false, sizeof(maze));
for (int i = 0; i < cnt_x; i++)
for (int j = 0; j < cnt_y; j++)
if (xblock[i].x >= yblock[j].stx && xblock[i].x <= yblock[j].edx
&& yblock[j].y >= xblock[i].sty && yblock[j].y <= xblock[i].edy)
maze[i][j] = true;
}

bool find(int u)
{
for (int i = 0; i < cnt_y; i++)
{
if (maze[u][i] && !isvisit[i])
{
isvisit[i] = true;
if (match[i] == -1 || find(match[i]))
{
match[i] = u;
return true;
}
}
}
return false;
}

int main()
{
cin >> row >> col;

for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
cin >> map[i][j];

build_graph();

memset(match, -1, sizeof(match));
int ans = 0;
for (int i = 0; i < cnt_x; i++)
{
memset(isvisit, false, sizeof(isvisit));
if (find(i))
ans++;
}

cout << ans << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: