二分图最大匹配

                                                                                                                           月老的难题

          月老的难题,这一题是最大匹配问题,求最大匹配的常见方法有贪心(对出度的贪心),最大流算法(加个源点和汇点),在这是匈牙利算法(寻找增广路,每找到一个增广路,配对加一)

这道题我是用匈牙利算法写的(刚学的),下面我说下我对这个算法的理解,在做这题前,我没用过邻接表存过图,就因为我想写下邻接表,这道题一搁搁了好几天。今天第一次写时,还是老习惯用邻接矩阵(菜呀),写好之后,运行了一下,果断超时。那只好老老实实地去写邻接表吧,幸亏以前看过,看着一个同学的模板,写了下邻接表,存图的问题解决了,那接着就得解决匈牙利算法:匈牙利算法的核心就是寻找增广路,增广路,在我理解里它就是交错路径,而交错路径是什么呢?我是这样理解的,假如有两个集合A,B,A集合里一个点a1,去匹配B集合里的一点b1,而B集合里点b1早已和A中的a2匹配,如果B中有b2可以和a2匹配的,那么我们就让它与a2与b2匹配,如果b2在A中已经有匹配a3,那么我们再让a3去找匹配…………就这样直到找到一个未匹配的点,这就是一条交错路径,我就是这样理解的。

     用最大流和贪心去做这道题,代码我没写呢,只是从网上看了些东西,知道了这些思路,改天再写,代码有些凌乱。

 
#include<stdio.h>
#include<string.h>
#define N 510
#define K 10005
struct
{
	int head;

}V[N];
struct
{
	int v,next;
}E[K];
int top,match[N],used[N];
void Add_Edge(int u,int v)
{
	E[top].v=v;
	E[top].next=V[u].head;
	V[u].head=top++;
}
int DFS(int u)
{
	int i,v;
	for(i=V[u].head;i!=-1;i=E[i].next)
	{
		v=E[i].v;
		if(!used[v])
		{
			used[v]=1;
			if(!match[v]||DFS(match[v]))
			{
				match[v]=u;
				return 1;
			}
		}
	
	}
	return 0;

}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		top=0;
		memset(match,0,sizeof(match));
		memset(V,-1,sizeof(V));
		int k,count,n,u,v,i;
		scanf("%d%d",&n,&k);
		for(i=0;i<k;i++)
		{
			scanf("%d%d",&u,&v);
			Add_Edge(u,v);
		
		}
		count=0;
		for(i=1;i<=n;i++)
		{
			memset(used,0,sizeof(used));
			if(DFS(i))
				count++;}
		printf("%d\n",count);}
}

        


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值