POJ2226 Muddy Fields(二分图最小点覆盖集)
题目给张R×C的地图,地图上*表示泥地、.表示草地,问最少要几块宽1长任意木板才能盖住所有泥地,木板可以重合但不能盖住草地。
把所有行和列连续的泥地(可以放一块木板铺满的)看作点且行和列连续泥地分别作为XY部,每一块泥地看作边。这样就构造出了一个二分图。
那么,问题就是在这个二分图中就是选出最少的点覆盖所有的边,即二分图最小点覆盖集,而二分图最小点覆盖集=二分图最大匹配。
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 2555
#define MAXM 2555*4 struct Edge{
int v,cap,flow,next;
}edge[MAXM];
int vs,vt,NE,NV;
int head[MAXN]; void addEdge(int u,int v,int cap){
edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].v=u; edge[NE].cap=; edge[NE].flow=;
edge[NE].next=head[v]; head[v]=NE++;
} int level[MAXN];
int gap[MAXN];
void bfs(){
memset(level,-,sizeof(level));
memset(gap,,sizeof(gap));
level[vt]=;
gap[level[vt]]++;
queue<int> que;
que.push(vt);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(level[v]!=-) continue;
level[v]=level[u]+;
gap[level[v]]++;
que.push(v);
}
}
} int pre[MAXN];
int cur[MAXN];
int ISAP(){
bfs();
memset(pre,-,sizeof(pre));
memcpy(cur,head,sizeof(head));
int u=pre[vs]=vs,flow=,aug=INF;
gap[]=NV;
while(level[vs]<NV){
bool flag=false;
for(int &i=cur[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[u]==level[v]+){
flag=true;
pre[v]=u;
u=v;
//aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
aug=min(aug,edge[i].cap-edge[i].flow);
if(v==vt){
flow+=aug;
for(u=pre[v]; v!=vs; v=u,u=pre[u]){
edge[cur[u]].flow+=aug;
edge[cur[u]^].flow-=aug;
}
//aug=-1;
aug=INF;
}
break;
}
}
if(flag) continue;
int minlevel=NV;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==) break;
level[u]=minlevel+;
gap[level[u]]++;
u=pre[u];
}
return flow;
} char map[][];
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=; i<n; ++i){
for(int j=; j<m; ++j) scanf(" %c",&map[i][j]);
}
int x=,y=,d[][]={};
for(int i=; i<n; ++i){
for(int j=; j<m; ){
if(map[i][j]=='.') ++j;
else{
++x;
while(j<m && map[i][j]=='*') d[i][j++]=x;
}
}
}
NE=;
memset(head,-,sizeof(head));
for(int j=; j<m; ++j){
for(int i=; i<n; ){
if(map[i][j]=='.') ++i;
else{
++y;
while(i<n && map[i][j]=='*') addEdge(d[i++][j],y+x,);
}
}
}
vs=; vt=x+y+; NV=vt+;
for(int i=; i<=x; ++i) addEdge(vs,i,);
for(int i=; i<=y; ++i) addEdge(i+x,vt,);
printf("%d\n",ISAP());
return ;
}
POJ2226 Muddy Fields(二分图最小点覆盖集)的更多相关文章
- [POJ] 2226 Muddy Fields(二分图最小点覆盖)
题目地址:http://poj.org/problem?id=2226 二分图的题目关键在于建图.因为“*”的地方只有两种木板覆盖方式:水平或竖直,所以运用这种方式进行二分.首先按行排列,算出每个&q ...
- POJ1325 Machine Schedule(二分图最小点覆盖集)
最小点覆盖集就是在一个有向图中选出最少的点集,使其覆盖所有的边. 二分图最小点覆盖集=二分图最大匹配(二分图最大边独立集) 这题A机器的n种模式作为X部的点,B机器的m种模式作为Y部的点: 每个任务就 ...
- POJ 3041 Asteroids (二分图最小点覆盖集)
Asteroids Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 24789 Accepted: 13439 Descr ...
- poj 2226 Muddy Fields(最小点覆盖+巧妙构图)
Description Rain has pummeled the cows' field, a rectangular grid of R rows and C columns (1 <= ...
- POJ 2226 Muddy Fields(最小点覆盖)题解
题意:一片r*c的地,有些地方是泥地,需要铺地板.这些地板宽1,长无限,但只能铺在泥地上不能压到其他地方,问你铺满所有泥地最少几块 思路:我们把一行中连续的泥地看成整体,并把所有横的整体里的点编成一个 ...
- poj 2226 Muddy Fields(最小点覆盖)
题意: M*N的矩阵,每个格不是*就是#. *代表水坑,#代表草地. 农民要每次可以用一块宽为1,长不限的木板去铺这个矩阵.要求这块木板不能覆盖草地.木板可以重复覆盖(即一块木板与另一块木板有 ...
- POJ 2226 Muddy Fields (最小点覆盖集,对比POJ 3041)
题意 给出的是N*M的矩阵,同样是有障碍的格子,要求每次只能消除一行或一列中连续的格子,最少消除多少次可以全部清除. 思路 相当于POJ 3041升级版,不同之处在于这次不能一列一行全部消掉,那些非障 ...
- 二分图变种之最小路径覆盖、最小点覆盖集【poj3041】【poj2060】
[pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=54859604 向大(hei)佬(e)势力学(di ...
- POJ 3041 Asteroids (最小点覆盖集)
题意 给出一个N*N的矩阵,有些格子上有障碍,要求每次消除一行或者一列的障碍,最少消除多少次可以全部清除障碍. 思路 把关键点取出来:一个障碍至少需要被它的行或者列中的一个消除. 也许是最近在做二分图 ...
随机推荐
- [素材资源] Android开发性能优化简介(非常不错的)
转自(http://www.starming.com/index.php?action=plugin&v=wave&tpl=union&ac=viewgrouppost& ...
- 5 个最受人喜爱的开源 Django 包
导读 Django 围绕“可重用应用”的思想建立:自包含的包提供了可重复使用的特性.你可以将这些可重用应用组装起来,在加上适用于你的网站的特定代码,来搭建你自己的网站.Django 具有一个丰富多样的 ...
- POJ 矩阵相乘 (随机化算法-舍伍德(Sherwood))
周三的算法课,主要讲了随机化算法,介绍了拉斯维加斯算法,简单的理解了为什么要用随机化算法,随机化算法有什么好处. 在处理8皇后问题的时候,穷举法是最费时的,回朔比穷举好点,而当数据量比较大的时候,如1 ...
- centos rm -rf 恢复删除的文件
Linux有时候执行了 rm -rf 等操作误删了文件绝对是一件可怕的事情,好在有一些解决的办法可以临时救急.这时我们就要用到一款叫做extundelete的工具了. 目录[-] 依赖 安装 查找要恢 ...
- 局域网所有机器都能连接MySQL数据库的设置命令
Sql代码: grant all privileges on *.* to root@"%" identified by 'abc' with grant option; flus ...
- 修改setup.py的源
方法一: 修改文件 ~/.pydistutils.cfg为: [easy_install] index_url = http://pypi.douban.com/simple 方法二: 直接在setu ...
- mysql sql维护常用命令
mysql修改表名,列名,列类型,添加表列,删除表列 alter table test rename test1; --修改表名 alter table test add column name v ...
- Xenomai
http://blog.csdn.net/robertsong2004/article/details/43889249 嵌入式系统的开发,如果对实时性要求不高,就可以使用Linux自身的实时补丁实现 ...
- MinGW/MSYS 交叉编译环境搭建
因为包的依赖关系不清楚,搭建时出错也不知道是什么原因,下面链接老外写的搭建步骤,写的非常详细还有脚本 已经编译的下载地址 http://ingar.satgnu.net/devenv/mingw32/ ...
- codeforces B. Petya and Staircases 解题报告
题目链接:http://codeforces.com/problemset/problem/362/B 题目意思:给出整数n和m,表示有n级楼梯和m级dirty的楼梯,接下来m个数表示对应是哪一个数字 ...