BZOJ2668: [cqoi2012]交换棋子 费用流

来源:互联网 发布:认识蘑菇 知乎 编辑:程序博客网 时间:2024/05/07 11:25

Description

有一个nm列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态。要求第i行第j列的格子只能参与mi,j次交换。

Input

第一行包含两个整数nm(1<=nm<=20)。以下n行为初始状态,每行为一个包含m个字符的01串,其中0表示黑色棋子,1表示白色棋子。以下n行为目标状态,格式同初始状态。以下n行每行为一个包含m个0~9数字的字符串,表示每个格子参与交换的次数上限。
 

Output

输出仅一行,为最小交换总次数。如果无解,输出-1。

Sample Input

3 3
110
000
001
000
110
100
222
222
222

Sample Output

4

看题目,要求很奇怪,可以交换相邻的棋子(注意对角线),从初状态到末状态,然后一些格子有限制:最多交换几次(注意限制是在格子上面而不是棋子上面)。这种要求很奇怪,但是变换一下再想,如果把黑白棋子看做只有黑棋子,然后看做是要求我们通过一定变化使黑棋子走到最终位置的话,题目就很好理解了,就是要让我们求黑子移动的最小长度。
所以就很容易想到费用流,将每个点拆成两个点,将点权表现在边权上。但是我们同时又发现一个问题,对于一次交换,会使用相邻两个格子各一次,一共会使用两次,所以我们得先将边权除以二,但是问题又来了,对于初始黑子在的点,与末尾黑子在的点,其实对于这个黑子他只用交换一次,所以只会使用1的流量,所以我们得把他的边权令为(x+1)/2,这个细节比较重要。
最后就是最坑的了,这题数据有初状态棋子数与末状态棋子数不同的情况。。。
2 0