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;

}

你可能感兴趣的:(robot)