51nod 1368:黑白棋 二分图最大匹配
有一个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示例
3 3 3 o.o .o. o.o 3 3 ... .o. ... 5 5 xxxxx xxoxx xo.ox xxoxx xxxxx
Output示例
5 8 4
二分图,将相邻的白棋和空格建边,求两者的最大匹配。最终结果是白棋的数量+空格的数量-匹配的数量。
代码:
#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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。