题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=654

 

题意:有一个N*M(N,M<=50)的棋盘,棋盘的每一格是三种类型之一:空地、草地、墙。机器人只能放在空地上。在同一行或同一列的两个机器人,若它们之间没有墙,则它们可以互相攻击。问给定的棋盘,最多可以放置多少个机器人,使它们不能互相攻击。


分析:本题也是二分图匹配的一个经典题目。我们将每一行,每一列被墙隔开,且包含空地的连续区域称作“块”。显然,在一个块之中,最多只能放一个机器人,我们把这些块编上号。同样,把竖直方向的块也编上号。如下图:


       


把每个横向块看作X部的点,竖向块看作Y部的点,若两个块有公共的空地,则在它们之间连边。于是,问题转化成这样的一个二分图:




代码:

#include <iostream>
#include <string.h>
#include <stdio.h>using namespace std;
const int N = 1250;char map[N][N];
int col[N][N],row[N][N];
int link[N],head[N];
bool vis[N];
int cnt,n,m;
int R,C;struct Edge
{int to;int next;
};Edge edge[N*N];void Init()
{cnt = 0;memset(head,-1,sizeof(head));memset(col,0,sizeof(col));memset(row,0,sizeof(row));
}void add(int u,int v)
{edge[cnt].to = v;edge[cnt].next = head[u];head[u] = cnt++;
}bool dfs(int u)
{for(int i=head[u]; ~i; i=edge[i].next){int v = edge[i].to;if(!vis[v]){vis[v] = 1;if(link[v] == -1 || dfs(link[v])){link[v] = u;return true;}}}return false;
}int match()
{int ans = 0;memset(link,-1,sizeof(link));for(int i=1; i<=R; i++){memset(vis,0,sizeof(vis));if(dfs(i)) ans++;}return ans;
}int main()
{int T,tt = 1;cin>>T;while(T--){Init();cin>>n>>m;for(int i=1; i<=n; i++)for(int j=1; j<=m; j++)cin>>map[i][j];R = C = 1;for(int i=1; i<=n; i++){for(int j=1; j<=m; j++){if(map[i][j] != '#' && row[i][j] == 0){for(int k=j; map[i][k] != '#' && k <= m; k++)row[i][k] = R;++R;}if(map[i][j] != '#' && col[i][j] == 0){for(int k=i; map[k][j] != '#' && k <= n; k++)col[k][j] = C;++C;}}}for(int i=1; i<=n; i++)for(int j=1; j<=m; j++)if(map[i][j] == 'o' && row[i][j] != 0 && col[i][j] != 0)add(row[i][j],col[i][j]);printf("Case :%d\n",tt++);printf("%d\n",match());}return 0;
}

典型题目:一张残缺的棋盘,用1*2的矩形去覆盖它,要求矩形不互相重叠。求矩形最多可以放多少个。


分析:将棋盘染成黑白相间,黑色方格作为左边的点,白色方格作为右边的点,相邻的黑白方格中间连一条边。对已经建好的图求最大匹配。

ZOJ1654(二分构图题典例)相关推荐

  1. GitHub霸榜项目:30万字图解算法题典,超全实用资源,狂揽6000星

    点击上方,选择星标或置顶,不定期资源大放送! 阅读大概需要5分钟 Follow小博主,每天更新前沿干货 来源|机器之心 这里有一份超值资源汇总,请查收. 对于计算机科学的学习者来说,算法是一门非常重要 ...

  2. 百亿题典之C++编程题面试题

    原文地址:百亿题典之C++编程题面试题作者:百亿题典 1. 在linked list中找倒数第N个结点 2. 倒转linked list 3. 二叉树的结点有指向parent的指针,求最近公共祖先 4 ...

  3. 5. 卡特兰数(Catalan)公式、证明、代码、典例.

    1. 定义 卡特兰数(卡塔兰数),英文名Catalan number,是组合数学中一个常出现在各种计数问题中出现的数列. 其前几项为(从第零项开始) : C0 = 1, C1 = 1, C2 = 2, ...

  4. 卡特兰数(Catalan)公式、证明、代码、典例.

    本文部分转自https://www.cnblogs.com/yuzilan/p/10626072.html,这位大牛对于卡特兰数的剖析可以说是非常非常详细了!感谢前辈的分享! 1. 定义 卡特兰数(卡 ...

  5. 极限与连续知识点总结_函数极限与连续性知识点及典例

    <函数极限与连续性知识点及典例>由会员分享,可在线阅读,更多相关<函数极限与连续性知识点及典例(44页珍藏版)>请在人人文库网上搜索. 1.高等数学,高等数学电子教案,.-高等 ...

  6. c语言程序设计理论考试,《C语言程序设计》理论试题库-程序题100例

    <<C语言程序设计>理论试题库-程序题100例>由会员分享,可在线阅读,更多相关<<C语言程序设计>理论试题库-程序题100例(59页珍藏版)>请在人人 ...

  7. PHOTOSHOP 500典例特制 EXE电子书[转载]

    PHOTOSHOP 500典例特制 EXE电子书 软件大小  21 MB    软件类别  原创绿化/电脑教程 运行环境 Win9X, WinXP, Win2000 授权方式  共享软件 软件等级   ...

  8. 高等数学证明题500例解析-徐兵

    高等数学证明题500例解析-徐兵 链接: https://pan.baidu.com/s/11zPApdQ0xYeBAH3UhazDKw 提取码: edax 复制这段内容后打开百度网盘手机App,操作 ...

  9. 【C语言典例】:倒置字符串

    [C语言典例]:倒置字符串 文章目录 [C语言典例]:倒置字符串 输入描述: 输出描述: 输入 输出 全部代码 结束语 链接: https://www.nowcoder.com/questionTer ...

最新文章

  1. c语言序列sequence,Sequence
  2. 吐血总结:AQS到底是什么?
  3. 发布订阅之topics
  4. java面向对象语言_Java到底是不是一种纯面向对象语言?
  5. 好代码是管出来的——使用GitHub
  6. 贪心算法(Greedy Algorithm)之霍夫曼编码
  7. 【Java】深入理解Java虚拟机的读书笔记
  8. 读计算机基础知识心得体会1000字,计算机学习个人心得体会1000字.doc
  9. .NET在蹉跎中一路前行1
  10. (学习笔记)JAVA开发需要掌握哪些技术?
  11. python实现自动批量下载邮箱附件--GUI
  12. c语言编程存款问题,c程序问题输入存款金额money存期yea...
  13. WinCC 7.3 + SQL server(杂)
  14. 清华操作系统课程(向勇、陈渝)笔记——第三章(一)(计算机体系结构/内存分层体系)
  15. C++ - 函数返回多个返回值的方法总结
  16. 弘辽科技:想做好标题优化,这些错误不能犯。
  17. MySQL表关联关系
  18. 关于c3p0报错:An attempt by a client to checkout a Connection has timed out
  19. 在云边公益——互联网金融与公益的完美结合
  20. php生成占位图,Laravel4创建一个占位图片服务例子

热门文章

  1. MybatisPlus添加操作
  2. ServletContext_功能_获取MIME类型
  3. webflux系列--基础
  4. Spring @Conditional
  5. Spring--总体架构
  6. zookeeper分布式锁避免羊群效应(Herd Effect)
  7. h5的fetch方法_你不需要jQuery(三):新AJAX方法fetch()
  8. python文件下载器代码_GitHub - applechi/pythonCollection: python代码集合(文件下载器、pdf合并、极客时间专栏下载、掘金小册下载、新浪微博爬虫等)...
  9. java web 之间通信,【Java】Web发展中通信的方式有哪些呢?
  10. Linux文件目录命名规则