前言
文化课选手,最近没多少时间写题解,这题做了快两周了。若题解有误,欢迎指出。
题目链接
题目大意
在平面直角坐标系内,有 \(n\) 个男性, \(n\) 个女性。将这些男女配对,每对男女若配对成功,将做出贡献,这些贡献会在输入中描述,若没有描述,则贡献为 \(1\) 。配对是有条件的,若在平面直角坐标系内的,将这对男女用线段连起来,若中间没有别的人(不分男女),且两点之间的距离小于一个定值,则可以配对,反之不能。求做的最大贡献。(注意,没有基友,不能百合,不能开后宫!!!)
易错点
其实是输入问题。
- 不区分大小写,先将名字全部转换为大写或小写。
- 没有描述的人之间贡献为 \(1\) 。
注意点就好了。
思路
男男女女的配对问题,很容易就想到是二分图带权匹配。其中,男性为左部点,女性为右部点,花费就为做的贡献。可以使用 \(KM\) 算法,但这里介绍使用费用流求解的二分图带权匹配。
费用流如何来求解二分图的带权匹配很简单:将源点与左部点连接起来,将汇点用右部点连接起来,左部点与右部点该咋连就咋连。其中,每条边的容量为 \(1\) ,花费就为这条边的贡献。
结合图像理解:

在本张路中,绿色的点是源点,粉色的点是汇点,红色的点是左部点,蓝色的点是右部点。
先明确匹配的一条重要性质:每个点只有能有一条匹配边。也就意味着每个点只能被利用一次。而源点与汇点就很好地限制了每个点的利用,源点到达汇点只需要经过 \(3\) 条边,且严格遵守源点->左部点->右部点->汇点这条路径走。对于 \(1\) 条匹配边来说,它会消耗源点到达它的左部点,它的右部点到达汇点这条边,这就意味着它的左部点和右部点不能再次利用,从而满足匹配的这条性质。
故而,按照上述方法建一张网络,对与这张网络跑一边最大费用最大流即可。本文使用著名又基础的 \(Edmond-Karp\) 算法实现。
C++代码
#include