把伞兵看成边,行列看成节点,转化为了带权二分图最小点覆盖。
加入超级源点和超级汇点,源点和所有行节点相连,所有列节点和汇点相连,如果a行b列有敌人,则把节点a和节点b相连。则问题又可以转化求最小割。
现在求源点和汇点之间的最小割。因为对任一敌人<a,b>,必然有source-->a-->b-->sink, 割的性质是"不存在一条从source到sink的路径", 故路径上的三条边<source,a>, <a,b>, <b,sink>中至少有一条边在割中,我们把<a,b>的权值设置为无限大,则其不可能被选中。于是割边集中必然有<source,a>和<b,sink>中的至少一条,也即对应选择了相应的行或列,我们把这些边的权值设置为花费,则最小割即是总花费的最小方案。
还有一个需要注意的地方是,这里问题是要求cost的乘积,可以通过使用log()把乘法先转换为加法,最后输出的时候再转换回去。