这是一道最小点覆盖问题,以前也做过类似的,但那道题没有权值,做法是点数减去二分图匹配数(如果构图时重复计算了,二分匹配数别忘了除2)。而这道题有权值,方法是加入超级源点和超级汇点,源点和所有行节点相连,所有列节点和汇点相连,权值为行或列的花费,如果a行b列有敌人,则把节点a和节点b相连,权值为无穷大。现在求源点和汇点之间的最小割,即最大流。
还有一个需要注意的地方是,这里问题是要求cost的乘积,可以通过使用log()把乘法先转换为加法,最后输出的时候再用exp()转换回去。
这道题还有几个地方把我恶心了,一是在精度控制上(cap[u][v]>flow[u][v]+1E-8),二是再g++中用printf时参数为lf有问题,要用f,vc++没有这个问题。