- 1、本文档共20页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
匈牙利算法详解
匈牙利算法
USACO 4.2.2 The Perfect Stall 完美的牛栏 stall4
最简单的求二分图最大匹配,最朴素的匈牙利算法解决。
?[Copy to clipboard]View Code CPP
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
75
76
77 /*
ID: cmykrgb1
PROG: stall4
LANG: C++
*/
#include iostream
#include fstream
#define MAX 402
#define PV 200
using namespace std;
ifstream fi(stall4.in);
ofstream fo(stall4.out);
int N,M,mat;
int adjl[MAX][MAX];
int match[MAX];
bool onpath[MAX];
?
void init()
{
int i,j,a,b;
fi N M;
for (i=1;i=N;i++)
{
fi a;
for (j=1;j=a;j++)
{
fi b;
adjl[i][ ++adjl[i][0] ]=b+PV;
adjl[b+PV][ ++adjl[b+PV][0] ]=i;
}
}
}
?
bool cross(int i)
{
int k,j;
for (k=1;k=adjl[i][0];k++)
{
j=adjl[i][k];
if (!onpath[j])
{
onpath[j]=true;
if (!match[j] || cross(match[j]))
{
match[j]=i;
return true;
}
}
}
return false;
}
?
void hungary()
{
int i;
for (i=1;i=N;i++)
{
if (cross(i))
mat++;
memset(onpath,0,sizeof(onpath));
}
}
?
void print()
{
fo mat endl;
fi.close();
fo.close();
}
?
int main()
{
init();
hungary();
print();
return 0;
}
这是一种用增广路求二分图最大匹配的算法。它由匈牙利数学家Edmonds于1965年提出,因而得名。 定义 未盖点:设Vi是图G的一个顶点,如果Vi 不与任意一条属于匹配M的边相关联,就称Vi 是一个未盖点。
交错路:设P是图G的一条路,如果P的任意两条相邻的边一定是一条属于M而另一条不属于M,就称P是一条交错路。
可增广路:两个端点都是未盖点的交错路叫做可增广路。
流程图
伪代码:
?[Copy to clipboard]View Code CPP
bool 寻找从k出发的对应项出的可增广路
{
while (从邻接表中列举k能关联到顶点j)
{
if (j不在增广路上)
{
把j加入增广路;
if (j是未盖点 或者 从j的对应项出发有可增广路)
{
修改j的对应项为k;
则从k的对应项出有可增广路,返回true;
}
}
}
则从k的对应项出没有可增广路,返回false;
}
?
void 匈牙利hungary()
{
for i-1 to n
{
if (则从i的对应项出有可增广路)
匹配数++;
}
输出 匹配数;
} 演示
C实现(作者CmYkRgB123)
?[Copy to clipboard]View Code CPP
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 #include stdio.h
#include
文档评论(0)