HDU 2063过山车 二分图最大匹配 匈牙利算法

这题属于二分图算法的入门题目。

就是要求二分图的最大匹配。求解最大匹配的算法为匈牙利算法。其核心思想就是从左半点集逐个出发寻找增广路径,每找到

一条增广路径,匹配数就加一。可以证明当找不到增广路径是就得到了最大匹配。

详细解释请参阅:点击打开链接

 

其中,useif[]是在同一次寻找增广路径是有用。主要是由于递归。比如如果之前已用过右点集中的1,下一次就不能再用了。

开始时初始化num=0,表示初始匹配为0。即表明左点集中每一点都是未用,也即都可以作为寻找增广路径的起点。

 

AC代码:

#include<iostream>
using namespace std;

const int MAX=501;
int lNum,rNum,k;
int link[MAX];    //记录当前与y点相连的x点
bool map[MAX][MAX];  //存储二分图,x到y有路径,则map[x][y]=true;反之,为false
bool useif[MAX];   //记录y中节点是否使用了(也就是男生是否已经被选)

void getMap()  //存图
{
	memset(map,false,sizeof(map));

	int x,y;
	for(int i=1;i<=k;i++)
	{
		cin>>x>>y;
		map[x][y]=true;
	}
}

bool can(int t)
{
	for(int i=1;i<=lNum;i++)
	{
		if(!useif[i] && map[t][i])
		{
			useif[i]=true;
			if(link[i]==-1 || can(link[i]))
			{
				link[i]=t;
				return true;
			}
		}
	}

	return false;
}

int maxMatch()
{
	int num=0;

	memset(link,0xff,sizeof(link));  //未连的计为-1
	for(int i=1;i<=rNum;i++)   //从右边点(女生)出发依次寻找增广路径
	{
		memset(useif,false,sizeof(useif));
		if(can(i)) num++;
	}

	return num;
}

int main()
{
	while(cin>>k,k)
	{
		cin>>rNum>>lNum;

		getMap();

		cout<<maxMatch()<<endl;
	}

	return 0;
}


 

 

 

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