51nod 1368:黑白棋 二分图最大匹配

来源:互联网 发布:天猫双11交易数据 编辑:程序博客网 时间:2024/05/16 12:42

1368 黑白棋
题目来源: TopCoder
基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题
 收藏
 取消关注
有一个N*M的棋盘(1<=N,M<=50),棋盘上有一些黑色的和白色的棋子。定义棋盘上两个位置相邻是指这两个格子存在公共边。已知棋盘中的白色棋子都不与其他白色棋子相邻。现在玩家可以向棋盘中空格的位置上放入一些黑色棋子,当一个白色棋子相邻的格子都被黑色的棋子占据的时候,这颗白色的棋子会被移出棋盘,而它原来的位置将变为空格,值得注意的是一些边界上的白色棋子其相邻的格子可能不足4个,但是只要这些格子里都是黑色,它就得移除。玩家的目的是放一些黑色的棋子后使棋盘上的空格最大化。求最优策略下棋盘上最多能有多少个空格?(空格指没有棋子的格子。)
Input
多组测试数据,第一行一个整数T,表示测试数据数量,1<=T<=5每组测试数据有相同的结构构成:每组数据的第一行有两个整数N,M,表示棋盘的大小,其中1<=N,M<=50.之后有一个N*M的字符矩阵S,表示棋盘初始状态,其中S[i][j]='.'表示(i,j)格式空的,S[i][j]='x'表示这个格子中有一个黑棋,S[i][j]='o'表示这个格子中有一个白棋。保证任意两颗白棋不相邻。
Output
每组数据一行输出,即棋盘上最多可能出现多少个空格.
Input示例
33 3o.o.o.o.o3 3....o....5 5xxxxxxxoxxxo.oxxxoxxxxxxx
Output示例
584

二分图,将相邻的白棋和空格建边,求两者的最大匹配。最终结果是白棋的数量+空格的数量-匹配的数量。

代码:

#include <iostream>#include <algorithm>#include <cmath>#include <vector>#include <string>#include <cstring>#include <map>#pragma warning(disable:4996)using namespace std;int n, m;int v1, v2;int link[2502];int visit[2502];char val[52][52];int grid[2502][2502];map<int, int>white;map<int, int>blank;bool bfs(int x){int i;for (i = v2; i >= 1; i--){if (grid[x][i] && visit[i] == 0){visit[i] = 1;if (link[i] == -1 || bfs(link[i])){link[i] = x;return true;}}}return false;}void Magyarors(){int i, sum;memset(link, -1, sizeof(link));sum = 0;for (i = v1; i >= 1; i--){memset(visit, 0, sizeof(visit));if (bfs(i)){sum++;}}cout << v1+v2-sum << endl;}int main(){//freopen("i.txt","r",stdin);//freopen("o.txt","w",stdout);int test, i, j, num_w, num_b, pos_w, pos_b;cin >> test;while (test--){memset(grid, 0, sizeof(grid));memset(val, 0, sizeof(val));white.clear();blank.clear();num_w = 0;num_b = 0;cin >> n >> m;for (i = 1; i <= n; i++){cin >> val[i] + 1;for (j = 1; j <= m; j++){if (val[i][j] == 'o'){white[i*m + j] = ++num_w;}if (val[i][j] == '.'){blank[i*m + j] = ++num_b;}}}v1 = num_w;v2 = num_b;for (i = 1; i <= n; i++){for (j = 1; j <= m; j++){if (val[i][j] == 'o'){pos_w = white[i*m + j];if (val[i - 1][j] == '.'){pos_b = blank[(i - 1)*m + j];grid[pos_w][pos_b] = 1;}if (val[i + 1][j] == '.'){pos_b = blank[(i + 1)*m + j];grid[pos_w][pos_b] = 1;}if (val[i][j + 1] == '.'){pos_b = blank[i*m + j + 1];grid[pos_w][pos_b] = 1;}if (val[i][j - 1] == '.'){pos_b = blank[i*m + j - 1];grid[pos_w][pos_b] = 1;}}}}Magyarors();}//system("pause");return 0;}



0 0