二分图匹配(匈牙利算法及其讲解)

点击打开链接


#include<stdio.h>
#include<string.h>

const int INF = 505;
 

int dfs(int u);			//搜索以u点为起点的增广路经,如果能搜到返回1,不能返回0;
 
int edge[INF][INF];		//以邻接矩阵的形式建立二分图。 

int n, k;

int vx[INF], vy[INF];	//vy存的是在y集合中已经匹配过的x点,所以匹配边i->j的表示方法为vy[i]=j; 
					 

int vis[INF];		//用来标记在搜索过程中某点是否已经在增广路中,如果已经在就不用在向增广路添加了。 

 
/*
3 4
1 1
1 3
2 2
3 2
Sample Output
2
*/
int main()
{
	scanf("%d %d",&n, &k);
	
	memset(edge, -1, sizeof(edge));
	
	for(int i=1; i <= k; i++)
	{
		int x, y;
		scanf("%d %d", &x, &y);
		edge[x][y] = 1;
	}
	
	memset(vx, -1, sizeof(vx));
	memset(vy, -1, sizeof(vy));		//一开始,二分图中没有点匹配。 
	
	int result = 0;					//一开始二分图匹配数为0;
	 
	for(int u = 1; u <= n; u++)		//对二分图中左边的每个点寻找增广路。 
	{
		memset(vis, 0, sizeof(vis));
		result += dfs(u) ;			//如果知道增广路,那么 匹配数+1; 
	}
	
	printf("%d\n", result) ;
	
	 
	
	
	
	return 0;
}

int dfs(int u)
{
	for(int v = 1; v <= n; v++)
	{
		if(edge[u][v] == 1 && vis[v] == 0)	//如果u,v两点之间有边(也就是两点可以匹配),
											//并且v不再增广路中
		{
			vis[v] = 1; 	//将 v点加入增广路。
			if(vy[v] == -1 ||dfs(vy[v]) == 1)	//如果该点为为非匹配点
												//或者能根据该点匹配的x中点找到未匹配点
			{
				vx[u] = v;						//翻转关系 
				vy[v] = u; 
				return 1;
			} 
		} 
	}
	return 0;
}

全部评论

相关推荐

本人什么都不会求求大家帮我选一个简单一点的
牛客798552099号:选10 目标检测真的很简单 网上随便找点改进的模块拼一下就可以了
点赞 评论 收藏
分享
我即大橘:耐泡王
点赞 评论 收藏
分享
牛客915519934号:差不多得了 ,真以为我们好忽悠呢?当初就是听了你们的话没有赶上风口入行Java,现在还想再忽悠我呢?这明显就是一个新风口,国家大力发展制造业,以后这个圈子的钱只会越来越多,不管是入门还是大佬,只要进来少说有你一口饭吃,一个个自私自利自己上了车就劝退其他人,钱都让你赚得了呗。就这点东西,入门很容易的,学个pcb,单片机就可以去找工作了,少说一万五起,以后只会越来越高,以后想进阶就去FPGA,linux,给的钱吊打互联网,再说说你们一直说数电模电难?实际呢也不过一个月就能拿下的事情,你不需要学的多深,只需要入门就足够了,就按我说的学出来少说两万起,最好报个培训班,入门更快,兄弟们跟着我冲就完事了,趁着这个机会,狠狠赚他一笔。
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务