POJ3041 Asteroids

考查:二分图最大匹配 最小顶点覆盖

提交情况:1次WA 一次AC

二分图最大匹配的问题一般用匈牙利算法解决,自己对匈牙利算法的理解就是在图中的每个点进行深度优先遍历,找到一条增广路径,然后对增光路径进行取反,直到找不到增广路径为止。因为增广路径是由不在匹配中的边和在匹配中的边交叉组成的,所以每反转一次匹配数就会增加1.具体的内容可以看下面的文章,说得非常好。

http://www.byvoid.com/blog/hungary/

http://imlazy.ycool.com/post.1603708.html

 AC_CODE:

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

int graph[502][502];
int visit[502];
int match[502];
int N,K;

int dfs(int v)
{
	int i;
	for(i=1;i<=N;i++)
	{
		if(graph[v][i]&&!visit[i])
		{
			visit[i]=1;
			if(match[i]==0||dfs(match[i]))
			{
				match[i]=v;
				return 1;
			}
		}
	}
	return 0;
}
void hungary()
{
	int i,cnt;
	cnt=0;
	for(i=1;i<=N;i++)
	{
		memset(visit,0,sizeof(visit));
		if(dfs(i)) cnt++;
	}
	printf("%d\n",cnt);
}
int main()
{
	int a,b;
	memset(graph,0,sizeof(graph));
	memset(match,0,sizeof(match));
	scanf("%d %d",&N,&K);
	while(K--)
	{
		scanf("%d %d",&a,&b);
		graph[a][b]=1;
	}
	hungary();
	return 0;
}

再说下代码和算法的具体关系。dfs函数的作用是从某个顶点v开始找一条增广路径,同时进行反转。过程是如果从v到另一个顶点v0有边而且另外一条边还没有被匹配,则就把v设为v0的匹配,或者如果v0已经被匹配了而且从v0开始可以找得到另外一条增广路径,则修改v0的匹配为v,这样就完成了反转。一般找不到增广路径时的情况为深度优先遍历到的最后一个点已经被匹配了,因为增广路径的起始点和结束点必须都为未匹配。

另外,二分图匹配还可以由HopCroft-Karp算法来做,它的复杂度为O(|E||V|^0.5),匈牙利算法的复杂度为O(|V||E|)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值