匈牙利算法

参见博客:http://blog.csdn.net/dark_scope/article/details/8880547,非常给力的说法 关于二分图匹配,常用的结论如下:

  1. 二分图的最小顶点覆盖 最小顶点覆盖要求用最少的点(X或Y中都行),让每条边都至少和其中一个点关联。 knoig定理:二分图的最小顶点覆盖数 = 二分图的最大匹配数(m)。

  2. DAG图的最小路径覆盖 用尽量少的不相交简单路径覆盖有向无环图(DAG)G的所有顶点,这就是DAG图的最小路径覆盖问题。 结论:DAG图的最小路径覆盖数 = 节点数(n)- 最大匹配数(m)

  1. 二分图的最大独立集 结论:二分图的最大独立集数 = 节点数(n)— 最大匹配数(m)

匈牙利算法模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
* Author: xtestw
* Created Time: 2014/7/6 21:55:04
* File Name: hungry.cpp
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <time.h>
using namespace std;
const int maxint = -1u>>1;
int g[1000][1001];
int vis[1010];
int pre[1010];
int m,n1,n2;
void init(){
memset(g,0,sizeof(g));
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre));
scanf("%d",&m);
if (m==0) return;
scanf("%d%d",&n1,&n2);
for(int i = 0; i < m ; i++)
{
int a,b;
scanf("%d%d",&a,&b);
g[a][b]=1;
}

}
int find(int x){
for(int i=1;i<=n2;i++)
{
if (g[x][i] && !vis[i]){
vis[i]=1;
if (pre[i]<0 || find(pre[i]))
{
pre[i]=x;
return 1;
}
}
}
return 0;
}
int hungry(){
int ret=0;
for(int i=1;i<=n1;i++)
{
memset(vis,0,sizeof(vis));
if (find(i)){
ret++;
}
}
return ret;
}
int main() {
#ifndef ONLINE_JUDGE
// freopen("f:/in.txt","r",stdin);
#endif
while (true){
init();
if (m==0) break;
cout<<hungry()<<endl;
}
return 0;
}
xtestw 微信 微信
欢迎关注我的其它发布渠道