匈牙利算法详解.docx

上传人:b****5 文档编号:11777468 上传时间:2023-04-01 格式:DOCX 页数:23 大小:1.12MB
下载 相关 举报
匈牙利算法详解.docx_第1页
第1页 / 共23页
匈牙利算法详解.docx_第2页
第2页 / 共23页
匈牙利算法详解.docx_第3页
第3页 / 共23页
匈牙利算法详解.docx_第4页
第4页 / 共23页
匈牙利算法详解.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

匈牙利算法详解.docx

《匈牙利算法详解.docx》由会员分享,可在线阅读,更多相关《匈牙利算法详解.docx(23页珍藏版)》请在冰豆网上搜索。

匈牙利算法详解.docx

匈牙利算法详解

匈牙利算法

USACO4.2.2ThePerfectStall完美的牛栏stall4

最简单的求二分图最大匹配,最朴素的匈牙利算法解决。

?

[Copytoclipboard]ViewCodeCPP

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

#include

#defineMAX402

#definePV200

usingnamespacestd;

ifstreamfi("stall4.in");

ofstreamfo("stall4.out");

intN,M,mat;

intadjl[MAX][MAX];

intmatch[MAX];

boolonpath[MAX];

 

voidinit()

{

inti,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;

}

}

}

 

boolcross(inti)

{

intk,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;

returntrue;

}

}

}

returnfalse;

}

 

voidhungary()

{

inti;

for(i=1;i<=N;i++)

{

if(cross(i))

mat++;

memset(onpath,0,sizeof(onpath));

}

}

 

voidprint()

{

fo<

fi.close();

fo.close();

}

 

intmain()

{

init();

hungary();

print();

return0;

}

这是一种用增广路求二分图最大匹配的算法。

它由匈牙利数学家Edmonds于1965年提出,因而得名。

定义未盖点:

设Vi是图G的一个顶点,如果Vi不与任意一条属于匹配M的边相关联,就称Vi是一个未盖点。

交错路:

设P是图G的一条路,如果P的任意两条相邻的边一定是一条属于M而另一条不属于M,就称P是一条交错路。

可增广路:

两个端点都是未盖点的交错路叫做可增广路。

流程图

伪代码:

?

[Copytoclipboard]ViewCodeCPP

bool寻找从k出发的对应项出的可增广路

{

while(从邻接表中列举k能关联到顶点j)

{

if(j不在增广路上)

{

把j加入增广路;

if(j是未盖点或者从j的对应项出发有可增广路)

{

修改j的对应项为k;

则从k的对应项出有可增广路,返回true;

}

}

}

则从k的对应项出没有可增广路,返回false;

}

 

void匈牙利hungary()

{

fori->1ton

{

if(则从i的对应项出有可增广路)

匹配数++;

}

输出匹配数;

}

演示

C实现(作者CmYkRgB123)

?

[Copytoclipboard]ViewCodeCPP

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

#include

#defineMAX102

 

longn,n1,match;

longadjl[MAX][MAX];

longmat[MAX];

boolused[MAX];

 

FILE*fi,*fo;

 

voidreadfile()

{

fi=fopen("flyer.in","r");

fo=fopen("flyer.out","w");

fscanf(fi,"%ld%ld",&n,&n1);

longa,b;

while(fscanf(fi,"%ld%ld",&a,&b)!

=EOF)

adjl[a][++adjl[a][0]]=b;

match=0;

}

 

boolcrosspath(longk)

{

for(longi=1;i<=adjl[k][0];i++)

{

longj=adjl[k][i];

if(!

used[j])

{

used[j]=true;

if(mat[j]==0||crosspath(mat[j]))

{

mat[j]=k;

returntrue;

}

}

}

returnfalse;

}

 

voidhungary()

{

for(longi=1;i<=n1;i++)

{

if(crosspath(i))

match++;

memset(used,0,sizeof(used));

}

}

 

voidprint()

{

fprintf(fo,"%ld",match);

fclose(fi);

fclose(fo);

}

 

intmain()

{

readfile();

hungary();

print();

return0;

}

Pascal实现(作者魂牛)

?

[Copytoclipboard]ViewCodePASCAL

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

var

a:

array[1..1000,1..1000]ofboolean;

b:

array[1..1000]oflongint;

c:

array[1..1000]ofboolean;

n,k,i,x,y,ans,m:

longint;

 

functionpath(x:

longint):

boolean;

var

i:

longint;

begin

fori:

=1tondo

ifa[x,i]andnotc[i]then

begin

c[i]:

=true;

if(b[i]=0)orpath(b[i])then

begin

b[i]:

=x;

exit(true);

end;

end;

exit(false);

end;

 

procedurehungary;

var

i:

longint;

begin

fillchar(b,sizeof(b),0);

fori:

=1tomdo

begin

fillchar(c,sizeof(c),0);

ifpath(i)theninc(ans);

end;

end;

 

begin

fillchar(a,sizeof(a),0);

readln(m,n,k);

fori:

=1tokdo

begin

readln(x,y);

a[x,y]:

=true;

end;

ans:

=0;

hungary;

writeln(ans);

end.

鸣谢:

魂牛

一点废话

在魂牛的帮助下,我终于正确得写出了了匈牙利算法,原来它这么好写啊。

感谢魂牛支持!

另外,hungary这个词容易让我联想到hungry。

饿了,我要去吃加餐了。

总算写完了,画图真累啊。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 起诉状

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1