poj 2226
来源:互联网 发布:centos png 编辑:程序博客网 时间:2024/06/16 13:39
题意:给出一个矩阵 , 每个点代表青草或者泥泞的路 , 问你最少要多少块木板(宽度为一个点的宽度 ,长度任意)才能把这些泥泞的路都盖住 , 并且不能把草盖住 , 木板可以重合 。
这题要是没加(不能把草盖住)这个条件 , 那么就是普通的最小路径覆盖 。
然而加了这个题之后 , 还是用最小路径覆盖 , 只不过要重新建过图。
最小路径覆盖 = 原图节点数 - 建图后的最大匹配 。
建图:分两步 , 1、从行开始 , 对么个点就行编号 , 如果在同一行并且相邻 , 那么就标记为一个编号 。
2、从列开始 , 做法和1一样 , 行跟列是分别单独进行的 。
之后把行构成的点 , 看成是X点集合 , 列看成是Y点集合 , 再根据原图每个点的行跟列进行连接 , 就可以够成一个二分图。
最近就只要用最下路径覆盖就能求出了 。
代码:
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 120;
int n , m , pre[2500] , lx[MAXN][MAXN] ,ly[MAXN][MAXN];
vectorgrap[2500];
bool s[2500];
int x , y;
void init()
{
for(int i =0; i <= n; i++)
grap[i].clear();
memset(lx ,0 , sizeof(lx));
memset(ly ,0, sizeof(ly));
}
bool can(int u)
{
for(int i =0 ; i < grap[u].size(); i++)
{
int v =grap[u][i] ;
if(!s[v])
{
s[v] =true;
if(pre[v] ==-1 || can(pre[v]))
{
pre[v] =u;
returntrue;
}
}
}
returnfalse;
}
int km()
{
int sum =0;
memset(pre ,-1 , sizeof(pre));
for(int i =1; i < x; i++)
{
memset(s ,false , sizeof(s));
if(can(i)) sum += 1;
}
returnsum;
}
int main()
{
while(scanf("%d %d" , &n , &m) != EOF)
{
getchar();
init();
inti ,j ;
x = 1 , y =1;
charcy[100][100];
for(i = 0 ;i < n; i++)
{
scanf("%s" ,cy[i]);
for(j = 0 ;j < m ; j++)
if(cy[i][j]== '*')
{
这题要是没加(不能把草盖住)这个条件 , 那么就是普通的最小路径覆盖 。
然而加了这个题之后 , 还是用最小路径覆盖 , 只不过要重新建过图。
最小路径覆盖 = 原图节点数 - 建图后的最大匹配 。
建图:分两步 , 1、从行开始 , 对么个点就行编号 , 如果在同一行并且相邻 , 那么就标记为一个编号 。
之后把行构成的点 , 看成是X点集合 , 列看成是Y点集合 , 再根据原图每个点的行跟列进行连接 , 就可以够成一个二分图。
最近就只要用最下路径覆盖就能求出了 。
代码:
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 120;
int n , m ,
vectorgrap[2500];
bool s[2500];
int x , y;
void init()
{
}
bool can(int u)
{
}
int km()
{
}
int main()
{