匈牙利算法(简单易懂)

匈牙利算法(简单易懂)

之前在网上看了一些匈牙利算法的题解,发现有两种情况:1.看不懂算法描述 2.看得懂算法描述,看不懂代码

1.二分图的定义

通俗点讲,就是有两个班的学生,可能A班的学生x和B班的学生y同意互相抄作业(两方都同意,即两个人都不会向老师打小报告),但是因为每个班的班主任很严,他们不允许自班到两个同学互相抄作业,也就是说A班的两个学生不能互相抄作业,B班的两个学生也不能互相抄作业。将每个学生看成一个点,互相抄过作业的连一条边,就是一个二分图。如图:
匈牙利算法(简单易懂)_第1张图片

二分图最大匹配

但是,可能会出现这种情况:A班的学生x同意和B班的所有人互相抄作业,A班的学生y只同意和B班到学生z抄作业,如果x和z一起抄作业,z就不想和y互相抄作业了(作业抄一份就够了),那么这样就会引发学生x和学生y的矛盾(因为学生y抄不了作业了)。于是,我们希望找到一种抄作业的分配方式,使不能抄作业的人最少。

匈牙利算法流程

匈牙利算法(简单易懂)_第2张图片
学生1说:我要抄A的作业!(后话:如愿以偿)
学生2说:我要抄B的作业!(目前如愿以偿)
学生3说:我要抄B的作业!(2竟敢和B互相抄作业)
学生3对学生2说:你敢和B抄作业!信不信我告老师?
学生2(怕了)说:那我去抄C的作业吧。(如愿以偿)
(学生3如愿以偿)
学生4说:我要抄C的作业!(2竟敢和C互相抄作业)
学生4对学生2说:你敢和C抄作业!信不信我告老师?
学生2说:反正我已经没有了退路,不管这么多了!
学生4说:。。。
总之,Hungary(匈牙利算法)的基本思路是:能和一个没有与他人合作的同学A互相抄作业就愉快地互相抄,假如发现想和一个同学A互相抄作业,但他已有了合作伙伴B,就威胁他的合作伙伴B,迫使他的合作伙伴B换去和另一人合作。B害怕被老师发现只好再找一个合作伙伴C,若C没有和他人合作,他俩就愉快地互相抄作业,但如果C已有合作伙伴D,B就威胁D让D换合作伙伴…直到有一个E换了合作伙伴为止。但假如B实在找不到一个新的合作伙伴,毕竟抄作业要紧,他不会向那个想和A互相抄作业的人妥协。于是那个想和A互相抄作业的人只好另去找合作伙伴,没找到的话只好自己做作业(即匹配失败)。

代码实现

bool Hungary(int fd){//fd要找人互相抄作业
	for(int i=1;i<=n;++i)
		if(c[fd][i]&&!vis[i]){//如果fd同意和i互相抄作业并且没有人威胁fd不能和i互相抄作业
			vis[i]=1;//威胁别人不能和i互相抄作业
			if(!fsp[i]||Hungary(fsp[i])){fsp[i]=fd;return true;}
			//i没有和其他人合作过 或 之前与i合作的人受到威胁,且找得到他人合作
			//即i与fd合作,匹配成功
		}
	return false;//fd找不到人互相合作,匹配失败
}

你可能感兴趣的:(匈牙利算法(简单易懂))