【模板】二分图最大匹配(匈牙利算法)/洛谷P3386

题目链接

https://www.luogu.com.cn/problem/P3386

题目大意

给定一个二分图,其左部点的个数为 \(n\),右部点的个数为 \(m\),边数为 \(e\),求其最大匹配的边数。

左部点从 \(1\)\(n\) 编号,右部点从 \(1\)\(m\) 编号。

题目解析

二分图最大匹配,一般用匈牙利算法完成。
匈牙利算法的本质,其实是不断尝试新匹配,修改旧匹配的 \(DFS\)
点数为 \(n\),边数为 \(m\)
时间复杂度: \(O(nm)\)

题目中采用了数组邻接表的存图方法,\(v[x]\) 表示新一轮是否访问数组,设成 \(i\) ,可以免去每轮清空数组的 \(memset\)

参考代码

#include <cstdio>
using namespace std;
int n, m, e, a, b, ans=0;
int h[1005], v[1005], p[1005];
struct AB{
	int a, b, n;
} d[1000005];
int match(int a)
{
	for (int j = h[a]; j ! =0; j = d[j].n)
	{
		int t = d[j].b;
		if (v[t] != i)
		{
			v[t] = i;
			if (!p[t] || match(p[t]))
			{
				p[t] = a;
				return 1;
			}
		}
	}
}
int main()
{
	scanf("%d%d%d",&n, &m, &e);
	for (int i = 1; i <= e; ++i)
	{
		scanf("%d%d",&a, &b);
		if (b > m)	continue;
		d[i].a = a;
		d[i].b = b;
		d[i].n = h[a];
		h[a] = i;
	}
	for (int i = 1; i <= n; ++i)
	{
		if (match(i)) ans++;
	}
	printf("%d\n",ans);
	return 0;
}

感谢支持!

posted @ 2020-09-22 00:03  Chiron-zy  阅读(218)  评论(0编辑  收藏  举报