有一个 m 行 n 列的方格图,每个方格中都有一个正整数。现要从方格中取数,使任意两个数所在方格没有公共边,且取出的数的总和最大,请求出最大的和。
输入格式
第一行是两个用空格隔开的整数,分别代表方格图的行数 m 和列数 n。
第 2 到第 (m+1) 行,每行 n 个整数,第 (i+1) 行的第 j 个整数代表方格图第 i 行第 j 列的的方格中的数字 ai,j。
输出格式
输出一行一个整数,代表和最大是多少。
输入输出样例
输入 #1
3 3
1 2 3
3 2 3
2 3 1
输出 #1
11
说明/提示
数据规模与约定
对于 $100\%$ 的数据,保证 1⩽n,m⩽100,1⩽ai,j⩽105。
提示
请注意输入的第一行先读入 m 再读入 n。
分析
首先明确题意:在一个 m×n 的方格图中取若干个数,设取出的数组成可重集 S,S 中任意两个数所在放个不能在相邻(共享同一条边),求 S 中所有元素和的最大值。
可以考虑一开始取所有方格,再删除权值和尽量小的方格,使得剩下的方格合法。假设取了方格 x,与其相邻的四个方格就都不可取了,可以注意到,与其相邻的四个方格的横纵坐标(行为横坐标,列为纵坐标)之和同 x 的横纵坐标之和相差 1,相差 1 意味着奇偶性不相同。可见,横纵坐标之和的奇偶性相同的两个点一定可以同时选取,而横纵坐标之和不同的两点可能会产生冲突。根据这一特性,可以建立二分图,将横纵坐标之和为偶数的点放入左部,横纵坐标之和为奇数的点放入右部。
二分图问题往往可以用网络流求解。建立超级源点 s 和超级汇点 t,s 向各个左部点连边,边权为对应方格的数字;各个右部点向 t 连边,边权为对应方格的数字;s 的出边和 t 的入边都存在,代表一开始选取所有方格中的数;若割去 s 的一条入边,那么该边指向的节点所代表的方格就不会被选取。接着在左右两部节点之间建边,左部各个点向其互相冲突的至多四个(上下左右)右部点连边;这时,一定存在从 s 到 t 的路径,这条路径一定会包含一对互相冲突的节点,设为 a,b,意味着存在 s 到 a 的边和 b 到 t 的边,即两个冲突的方格同时被选取;我们的任务是割去一些 s 的出边和 t 的入边,使得 s 和 t 互不相通,且割去的边的边权要尽量小,这就联想到了最小割。将左右两部之间的边的边权设为 +∞,该网络最小割即为要舍弃的方格中的数的总和,所有方格中数字的和减去舍弃方格中的数的总和即为答案。
最后,最大流等于最小割,建完图跑一遍 Dinic 算法即可。