POJ 3020 最小路径覆盖 = 顶点数-最大匹配数 二分匹配

九野的博客,转载请注明出处:http://blog.csdn.net/acmmmm/article/details/12841003

题意:

t个测试数据, n*m 的矩阵

用1*2的格子覆盖 所有 *   (1*2格子可重叠) 问最少需要多少个

 

此题和1507同出一辙,修改一下就可以了, 图中'O' 相当于1507中的坏点

答案则是1507的答案加上未使用的白点数

 

注意因为建的是无向二分图,最大匹配数结果是翻倍的

 

#include
#include
#include
#include

#define N 60
#define M 51
using namespace std;
int map[N][N];
int n,m;
int lef[N*N], pn;//lef[v]表示Y集的点v 当前连接的点  
bool T[N*N];     //T[u] 表示Y集 u 是否已连接X集
vectorG[N*N]; //匹配边  G[X集].push_back(Y集)  注意G 初始化

bool match(int x){ // x和Y集 匹配 返回x点是否匹配成功
	for(int i=0; in || y1>m || x>n || y>m)return ;
	if(map[x1][y1]==0 || map[x][y] == 0)return ;

	G[x*M+y].push_back(x1*M+y1);
}
void Have_map(){
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			if(map[i][j])
			{
				zouni(i,j,i+1,j);
				zouni(i,j,i,j+1);
				zouni(i+1,j,i,j);
				zouni(i,j+1,i,j);
			}
}
void init(){
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			G[i*M+j].clear();
}
char s[N];
int main(){
	int i,j,t;scanf("%d",&t);
	while(t--){
		int point=0;
		memset(map,0,sizeof(map));
		init();

		scanf("%d %d",&n,&m);	getchar();
		
		for(i=1;i<=n;i++){
			scanf("%s",s);
			for(j=0;j>1));
	}

	return 0;
}

/*
2
7 9
ooo**oooo
**oo*ooo*
o*oo**o**
ooooooooo
*******oo
o*o*oo*oo
*******oo
10 1
*
*
*
o
*
*
*
*
*
*

*/


 

你可能感兴趣的:(二分图相关)