题目来源: 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示例
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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

51nod 1368:黑白棋 二分图最大匹配的更多相关文章

  1. 51nod 2006 飞行员配对(二分图最大匹配) 裸匈牙利算法 求二分图最大匹配题

    题目: 题目已经说了是最大二分匹配题, 查了一下最大二分匹配题有两种解法, 匈牙利算法和网络流. 看了一下觉得匈牙利算法更好理解, 然后我照着小红书模板打了一遍就过了. 匈牙利算法:先试着把没用过的左 ...

  2. 51Nod 2006 飞行员配对(二分图最大匹配)

    第二次世界大战时期,英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2名飞行员,其中1名是英国飞行员,另1名是外籍飞行员.在众多的飞行员中, ...

  3. 51Nod 2006 飞行员配对(二分图最大匹配)-匈牙利算法

    2006 飞行员配对(二分图最大匹配) 题目来源: 网络流24题 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 第二次世界大战时期,英国皇家空军从沦陷国 ...

  4. 【BZOJ1854】[Scoi2010]游戏 二分图最大匹配

    [BZOJ1854][Scoi2010]游戏 Description lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当 ...

  5. POJ 2226二分图最大匹配

    匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图 ...

  6. 用Dart写的黑白棋游戏

    2013年11月,Dart语言1.0稳定版SDK发布,普天同庆.从此,网页编程不再纠结了. 在我看来,Dart语法简直就是C#的升级版,太像了.之所以喜欢Ruby的一个重要理由是支持mixin功能,而 ...

  7. POJ2239 Selecting Courses(二分图最大匹配)

    题目链接 N节课,每节课在一个星期中的某一节,求最多能选几节课 好吧,想了半天没想出来,最后看了题解是二分图最大匹配,好弱 建图: 每节课 与 时间有一条边 #include <iostream ...

  8. poj 2239 二分图最大匹配,基础题

    1.poj 2239   Selecting Courses   二分图最大匹配问题 2.总结:看到一个题解,直接用三维数组做的,很巧妙,很暴力.. 题意:N种课,给出时间,每种课在星期几的第几节课上 ...

  9. UESTC 919 SOUND OF DESTINY --二分图最大匹配+匈牙利算法

    二分图最大匹配的匈牙利算法模板题. 由题目易知,需求二分图的最大匹配数,采取匈牙利算法,并采用邻接表来存储边,用邻接矩阵会超时,因为邻接表复杂度O(nm),而邻接矩阵最坏情况下复杂度可达O(n^3). ...

随机推荐

  1. python闯关之路一(语法基础)

      1,什么是编程?为什么要编程? 答:编程是个动词,编程就等于写代码,那么写代码是为了什么呢?也就是为什么要编程呢,肯定是为了让计算机帮我们搞事情,代码就是计算机能理解的语言. 2,编程语言进化史是 ...

  2. dpkg 命令

    dpkg 是Debian Package的简写,是为Debian 专门开发的套件管理系统,方便软件的安装.更新及移除.所有源自Debian的Linux发行版都使用dpkg,例如Ubuntu.Knopp ...

  3. leetCode练题——9. Palindrome Number

    1.题目 9. Palindrome Number   Determine whether an integer is a palindrome. An integer is a palindrome ...

  4. String类为什么是不可变的

    String类为啥是final的? 我们找到string的jdk源码 1.看到String类被final修饰.这里你就要说出被final修饰的类不能被继承,方法不能被重写,变量不能被修改. 2.看到f ...

  5. Activiti工作流学习笔记一

    Activiti工作流 一:Activiti第一天 1:工作流的概念 说明: 假设:这两张图就是华谊兄弟的请假流程图 图的组成部分: 人物:范冰冰冯小刚王中军 事件(动作):请假.批准.不批准 工作流 ...

  6. Centos7 nginx配置多虚拟主机过程

    一.前提准备 1.已经安装好了的Centos7服务器 2.ip 为192.168.1.209   [本次的配置ip] 3.确定防火墙等已经关闭 二.nignx配置文件参数详解 要配置多台虚拟主机,就需 ...

  7. Python 基础之集合相关操作与函数和字典相关函数

    一:集合相关操作与相关函数 1.集合相关操作(交叉并补) (1)intersection() 交集 set1 = {"one","two","thre ...

  8. Python查询Redis中的Key

    今日,大哥让我查下项目的在线用户量,听到这个消息顿时懵逼了,在线用户量,这个该怎么查????想到项目中的登陆用户缓存信息Token都存放在Redis中,是不是可以根据Redis中Token的个数大致估 ...

  9. hdu 1599 find the mincost route floyd求无向图最小环

    find the mincost route Time Limit: 1000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  10. RedHat OpenShift QuickStart 1.1 OpenShift基础

    openshift 提供了命令行工具和web可视化页面,这些工具通过REST API去和openshift交互 一.开始为开发人员使用OpenShift 1. 探索命令行 2. 探索web conso ...