在一个n*m的草地上,.代表草地,*代表水,现在要用宽度为1,长度不限的木板盖住水,

木板可以重叠,但是所有的草地都不能被木板覆盖。

问至少需要的木板数。

这类题的建图方法:

把矩阵作为一个二分图,以行列分别作为2个顶点集

首先以每一行来看,把这一行里面连续的*编号,作为一个顶点

再以每一列来看,把这一列里面连续的*编号,作为一个顶点

则每一个*都有2个编号,以行看时有一个,以列看时有一个,则把这2个编号连边,容量为1

再建一个源点,连接所有行的编号,一个汇点,连接所有列的编号

这道题要求的是,所有*都被覆盖,即找到一个顶点的集合S,使得任意边都有至少一个顶点属于

S,即求一个点集顶点覆盖S,又要木板数最少,所以求的就是最小顶点覆盖。

最小顶点覆盖怎么求?

二分图中,有:

最小顶点覆盖=最大匹配

所以这道题就转化为求二分图的最大匹配了

再转化为最大流dinic算法。

 #include<cstdio>
#include<cstring>
#include<vector>
#include<queue> using namespace std; const int maxn=;
const int inf=0x3f3f3f3f;
const int s=;
int t;
int tota;
int totb; inline int min(int x,int y)
{
return x<y?x:y;
} struct Edge
{
int to,cap,rev;
};
vector<Edge>edge[maxn];
int iter[maxn];
int level[maxn];
char str[][];
int hash[][]; void addedge(int from,int to,int cap)
{
edge[from].push_back((Edge){to,cap,edge[to].size()});
edge[to].push_back((Edge){from,,edge[from].size()-});
} void build_graph(int n,int m)
{
for(int i=;i<n*m;i++)
edge[i].clear();
tota=;
for(int i=;i<=n;i++)
{
int j=;
while(j<=m)
{
if(str[i][j]=='*')
{
tota++;
hash[i][j]=tota;
while(j<=m&&str[i][j+]=='*')
{
j++;
hash[i][j]=tota;
}
}
j++;
}
}
totb=tota;
for(int j=;j<=m;j++)
{
int i=;
while(i<=n)
{
if(str[i][j]=='*')
{
totb++;
addedge(hash[i][j],totb,);
while(i<=n&&str[i+][j]=='*')
{
i++;
addedge(hash[i][j],totb,);
}
}
i++;
}
}
t=tota+totb+;
for(int i=;i<=tota;i++)
addedge(s,i,);
for(int i=tota+;i<=totb;i++)
addedge(i,t,);
} void bfs()
{
memset(level,-,sizeof level);
queue<int>que;
while(!que.empty())
que.pop();
que.push(s);
level[s]=;
while(!que.empty())
{
int u=que.front();
que.pop();
for(int i=;i<edge[u].size();i++)
{
Edge &e=edge[u][i];
if(e.cap>&&level[e.to]<)
{
level[e.to]=level[u]+;
que.push(e.to);
}
}
}
} int dfs(int u,int f)
{
if(u==t)
return f;
for(int &i=iter[u];i<edge[u].size();i++)
{
Edge &e=edge[u][i];
if(e.cap>&&level[e.to]>level[u])
{
int d=dfs(e.to,min(f,e.cap));
if(d>)
{
e.cap-=d;
edge[e.to][e.rev].cap+=d;
return d;
} }
}
return ;
} int solve()
{
int flow=;
while(true)
{
bfs();
if(level[t]<)
return flow;
memset(iter,,sizeof iter);
int f;
while(f=dfs(s,inf))
{
flow+=f;
}
}
} int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=;i<=n;i++)
{
scanf("%s",str[i]+);
}
build_graph(n,m);
printf("%d\n",solve());
}
return ;
}

POJ2226 Muddy Fields 二分匹配 最小顶点覆盖 好题的更多相关文章

  1. poj2226-Muddy Fields二分匹配 最小顶点覆盖 好题

    题目 给到一个矩阵,有些格子上是草,有些是水.需要用宽度为1,长度任意的若干块木板覆盖所有的水,并不能覆盖草,木板可以交叉,但只能横竖放置,问最少要多少块板. 分析 经典的矩阵二分图构图和最小点覆盖. ...

  2. poj 2226 Muddy Fields (二分匹配)

    Muddy Fields Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7340   Accepted: 2715 Desc ...

  3. POJ 1498[二分匹配——最小顶点覆盖]

    题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=1498] 题意:给出一个大小为n*n(0<n<100)的矩阵,矩阵中放入m种颜色(标号为1 ...

  4. [USACO2005][POJ2226]Muddy Fields(二分图最小点覆盖)

    题目:http://poj.org/problem?id=2226 题意:给你一个字符矩阵,每个位置只能有"*"或者“.",连续的横着或者竖的“*"可以用一块木 ...

  5. POJ2226 Muddy Fields(二分图最小点覆盖集)

    题目给张R×C的地图,地图上*表示泥地..表示草地,问最少要几块宽1长任意木板才能盖住所有泥地,木板可以重合但不能盖住草地. 把所有行和列连续的泥地(可以放一块木板铺满的)看作点且行和列连续泥地分别作 ...

  6. nyoj 237 游戏高手的烦恼 二分匹配--最小点覆盖

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=237 二分匹配--最小点覆盖模板题 Tips:用邻接矩阵超时,用数组模拟邻接表WA,暂时只 ...

  7. poj2226 Muddy Fields 填充棒子(二分匹配)

    参考博客:https://blog.csdn.net/liujc_/article/details/51287019 参考博客:https://blog.csdn.net/acdreamers/art ...

  8. UVA 11419 SAM I AM(最大二分匹配&最小点覆盖:König定理)

    题意:在方格图上打小怪,每次可以清除一整行或一整列的小怪,问最少的步数是多少,又应该在哪些位置操作(对输出顺序没有要求). 分析:最小覆盖问题 这是一种在方格图上建立的模型:令S集表示“行”,T集表示 ...

  9. HDU 3861 The King’s Problem(tarjan缩点+最小路径覆盖:sig-最大二分匹配数,经典题)

    The King’s Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

随机推荐

  1. spark 分析sql内容再插入到sql表中

    package cn.spark.study.core.mycode_dataFrame; import java.sql.DriverManager;import java.util.ArrayLi ...

  2. hdu3594 强连通(仙人掌图)

    题意:给定一张有向图,问是否是仙人掌图.仙人掌图的定义是,首先,这张图是一个强连通分量,其次所有边在且仅在一个环内. 首先,tarjan可以判强连通分量是否只有一个.然后对于所有边是否仅在一个环内,我 ...

  3. C语言中强制数据类型转换(转)

    原文地址不详 字符型变量的值实质上是一个8位的整数值,因此取值范围一般是-128-127,char型变量也可以加修饰符unsigned,则unsigned char 型变量的取值范围是0-255(有些 ...

  4. 黑马程序员——JAVA基础之程序控制流结构之判断结构,选择结构

    ------- android培训.java培训.期待与您交流! ---------- 程序控制流结构:顺序结构:判断结构:选择结构:循环结构. 判断结构:条件表达式无论写成什么样子,只看最终的结构是 ...

  5. (转)The 9 Deep Learning Papers You Need To Know About (Understanding CNNs Part 3)

    Adit Deshpande CS Undergrad at UCLA ('19) Blog About The 9 Deep Learning Papers You Need To Know Abo ...

  6. 如何才能将Faster R-CNN训练起来?

    如何才能将Faster R-CNN训练起来? 首先进入 Faster RCNN 的官网啦,即:https://github.com/rbgirshick/py-faster-rcnn#installa ...

  7. Python元组的简单介绍

    1.实际上元组是跟列表非常相近的另一种容器类型.元组和列表看上去的不同的一点是元组用圆括号而列表用方括号.而在功能上,元组是一种不可变的类型.正是因为这个原因,元组可以做一些列表不可以做的事情,比如用 ...

  8. cacti

    http://www.cacti.net/downloads/docs/html/index.html Cacti脚本及模板论坛:http://forums.cacti.net/forum-12.ht ...

  9. 树莓派 2 win 10 IOT

    Setting up Windows 10 for IoT on your Raspberry Pi This week at the BUILD conference in San Francisc ...

  10. JavaScript中类的实现机制

    理解类的实现机制在前面已经讲过,在JavaScript中可以使用function关键字来定义一个“类”.现在介绍如何为类添加成员.其过程很简单,在函数内通过this指针引用的变量或者方法都会成为类的成 ...