POJ2226 Muddy Fields

这是个最大匹配的经典题,个人推荐做一做,对建模的理解会更深刻。

总的来说,就是以每个横向的连续污点构成一个X点,以每个纵向的连续污点构成一个Y点,若横向与纵向同时覆盖了一个点,则连接XY。

构图完毕,然后用匈牙利算法。

#include <cstdio>
#include <cstring>

const int maxr = 60;
const int maxn = 1000;
int un,vn,r,c;
char mp[maxr][maxr];
int g[maxn][maxn],a[maxr][maxr],b[maxr][maxr];
int link[maxn];
bool vis[maxn];

bool dfs(int u)
{
	for (int v = 0; v < vn; v++)
	{
		if (g[u][v] && !vis[v])
		{
			vis[v] = 1;
			if (link[v]==-1 || dfs(link[v]))
			{
				link[v] = u;
				return 1;
			}
		}
	}
	return 0;
}

int KM()
{
	int res = 0;
	memset(link, -1, sizeof(link));
	memset(vis, 0, sizeof(vis));
	for (int u = 0; u < un; u++)
	{
		if (dfs(u))
		{
			res++;
			memset(vis, 0, sizeof(vis));
		}
	}
	return res;
}

int main()
{
	while (scanf("%d%d",&r,&c)==2)
	{
		memset(g,0,sizeof(g));
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		for (int i=0;i<r;i++) scanf("%s",mp[i]);
		un=0;
		for (int i=0;i<r;i++)
			for (int j=0;j<c;j++)
			{
				if (mp[i][j]=='*')
				{
					a[i][j]=un;
					if (mp[i][j+1]!='*') un++;
				}
			}
		vn=0;
		for (int j=0;j<c;j++)
			for (int i=0;i<r;i++)
			{
				if (mp[i][j]=='*')
				{
					b[i][j]=vn;
					if (mp[i+1][j]!='*') vn++;
				}
			}
		for (int i=0;i<r;i++)
			for (int j=0;j<c;j++)
				if (mp[i][j]=='*')
					g[a[i][j]][b[i][j]]=1;
		int ans=KM();
		printf("%d\n",ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值