• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

  • 联系
  • 订阅
  • 管理

View Post

zoj 1654 Place the Robots 最大二分匹配

        转换成最大匹配。

        每个横向的'o’和'#’块(必须包含'o’)作为X集合一个顶点,每个纵向的'o’和'#’块(必须包含'o’)作为Y集合一个顶点

        当横向块和纵向块的交点的'o’时,二分图该两个顶点有边相连接。

        这题因为下标不小心打错了,调了很久才ac,纳闷。

 

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

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

struct hori_block
{
	int row;
	int col_left, col_right;
};

struct ver_block
{
	int col;
	int row_up, row_dow;
};

hori_block X[MAX];
ver_block Y[MAX];

char map[N][N];
bool maze[MAX][MAX];

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

int row, col;
int cnt_x, cnt_y;

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] == 'o')
			{
				X[cnt_x].row = i;
				for (int k = j; k >= 0; k--)
					if (map[i][k] != '#')
						X[cnt_x].col_left = k;
					else
						break;

				while (j < col && map[i][j] != '#')
				{
					X[cnt_x].col_right = j;
					j++;	
				}
				cnt_x++;
			}
			
		}

	for (int j = 0; j < col; j++)
		for (int i = 0; i < row; i++)
		{
			if (map[i][j] == 'o')
			{
				Y[cnt_y].col = j;
				for (int k = i; k >= 0; k--)
					if (map[k][j] != '#') 
						Y[cnt_y].row_up = k;
					else
						break;

				while (i < row && map[i][j] != '#')
				{
					Y[cnt_y].row_dow = 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 (X[i].row >= Y[j].row_up && X[i].row <= Y[j].row_dow
				&& Y[j].col >= X[i].col_left && Y[j].col <= X[i].col_right
				&& map[ X[i].row ][ Y[j].col ] == 'o')
				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 max_match()
{
	int ans = 0;
	memset(match, -1, sizeof(match));

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

	return ans;
}

int main()
{
	int cases;

	cin >> cases;

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

		build_graph();

		cout << "Case :" << k << endl;
		cout << max_match() << endl;
	}
	return 0;
}

posted on 2011-02-09 23:19  sysuwhj  阅读(424)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3