二分图匹配:匈牙利算法

例题:点击这里

#include 
#include //二分图匹配可以理解为有n个女孩,m个男孩
//每个女孩喜欢0~m个男孩,每个男孩喜欢0~n个女孩
#include //求一种配对方式使得情侣的对数最多

//如果后来的和以前的发生矛盾,则被绿的优先退让。
//如果以前的退让之后没有cp可处,则以前的拒绝退让,新来的去寻找下一个匹配。
//如果新来的谁也匹配不上了,那就这么单着吧。

#include
#include
#include 
using namespace std;
const long long inf=2147483647;
#define maxd 1005
#define maxm 500000+5
struct Edge{
	int to,next;
}edge[50000+5];
int n,m,e;
int head[maxd];
int use[maxd];//表示是否匹配过
int match[maxd];//存储匹配的人
int cnt=0;
void addedge(int u,int v){
	edge[cnt].to = v; 
	edge[cnt].next = head[u];
	head[u] = cnt++;
}//链式前向星存边
bool dfs(int u){//给女孩u配对
	for(int i=head[u];i!=-1;i=edge[i].next){
		int v=edge[i].to;
		if(!use[v]){//u没有对象
			use[v]=true;//标记为有
			if(match[v]==-1||dfs(match[v])){//男孩v没对象,给女孩u组cp
			//或者男孩v有对象,则用女孩u更换原来的
				match[v]=u;//现在男孩v是女孩u的
				return true;
			}
		}
	}
	return false;//女孩u没有喜欢的男孩,或者更换不成功
}
int hungary(){
	int ans=0;
	for(int i = 1; i <= n;i++){
 		memset(use,false,sizeof(use));
 		if(dfs(i)) ans++;
 		//第i个配对成功,配对在之后可能会更换,但是保证能配对
	}
	return ans;
}
int main() {
	scanf("%d%d%d",&n,&m,&e);
	memset(head,-1,sizeof(head));
	memset(match,-1,sizeof(match));
	for(int i=0;i<e;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		addedge(u,v);
	}
	printf("%d",hungary());
	return 0;
}

你可能感兴趣的:(图论,二分图,匈牙利算法,算法,图论)