poj3020 二分图最大匹配(匈牙利算法)

不懂该题以及二分图相关概念的可以看一下这个博客 http://blog.csdn.net/steven030143/article/details/5917969

本人初学匈牙利算法,懂得也不是很透彻,但是自己写的代码也AC了,心里还是有点小激动,关于二分图还得好好练练。。。


现在复习此题,明白是如何将问题转化为最大匹配问题的了,

poj3020 二分图最大匹配(匈牙利算法)_第1张图片

建图:本代码是记录座城市的坐标,求最大匹配时,判断城市四周是否有相邻的城市,由于每座城市都要遍历一次它的四周,所以所求的匹配数会加倍,途中的最大匹配数明显为4(求得的值为8,加倍了),最大匹配中一条边覆盖两座城市,那么现在覆盖了8座城市,总共是12个城市,剩下单独的4座城市,这四座城市每座城市都需要一个圈来覆盖,则总共需要12-4*2+4=12-4=8个圈。

代码如下:

#include <iostream>
using namespace std;
#define HIGH 41
#define WIDE 11
int map[HIGH][WIDE];
int match[HIGH*WIDE];
bool visit[HIGH*WIDE];
int h,w,v_num;

struct NODE
{
	int x,y;
} node[HIGH*WIDE];

bool path(int id)
{
	int i;
	
	for ( i = 0; i < v_num; i++ )
	{
		if (!visit[i])
		{
			if ( (node[i].x==node[id].x&&(node[i].y==node[id].y+1||node[i].y==node[id].y-1))
				||(node[i].y==node[id].y&&(node[i].x==node[id].x+1||node[i].x==node[id].x-1)) )
			{
				visit[i] = true;
				if ( match[i] == -1 || path(match[i]) )
				{
					match[i] = id;
					return true;
				}
			}
		}
	}
	return false;
}

int main()
{
	int cas;
    int i,j;
    char ch;
    int result;
	
	cin >> cas;
	while ( cas-- )
	{
		memset(map,0,sizeof(map));
		memset(match,-1,sizeof(match));
		cin >> h >> w;
		v_num = 0;
		for ( i = 0; i < h; i++ ){
			for ( j = 0; j < w; j++ )
			{
				cin >> ch;
				if ( ch == '*' )
				{
					node[v_num].x = j;
					node[v_num].y = i;
					v_num++;
				}
			}
		}
		result = 0;
		for ( i = 0; i < v_num; i++ )
		{
			memset(visit,false,sizeof(visit));
			if ( path(i) )
				result++;
		}
		cout << v_num-result/2 << endl;
	}
	return 0;
}


 

你可能感兴趣的:(算法,Path)