参考:http://hi.baidu.com/%CD%F4%BD%ADwangjiang/blog/item/aa3bc8ec3d549edbb31cb1a3.html
http://apps.hi.baidu.com/share/detail/31832477
题意:现在有一个n*m的方阵,方阵里面的数字未知,但是我们知道如下约束条件:
1> 每一行的数字的和
2> 每一列的数字的和
3> 某些格子有特殊的大小约束,用大于号,小于号和等于号表示
求解是否存在在满足所有的约束的条件下用正数来填充该方阵的方案,若有,输出填充后的方阵,否则输出IMPOSSIBLE.
这道题可以转化成容量有上下界的最大流问题,将方阵的行从1……n编号,列n+1……n+m编号,添加源点s=0和汇点t=n+m+1.
1> 将源点和每一个行节点相连,相连所形成的边的容量的上下界都置为该行所有数字的和
2> 将每一个列节点和汇点相连,相连所形成的边的容量的上下界都置为该列所有数字的和
3> 如果u行v列的数字大于w,则将行节点u和列节点v+n相连,w为该边容量的下界,即置low[u][v+n]=max(low[u][v+n],w+1)
4> 如果u行v列的数字小于w,则将行节点u和列节点v+n相连,w为该边容量的上界,即置high[u][v+n]=min(high[u][v+n],w-1)
5> 如果u行v列的数字等于w,则将行节点u和列节点v+n相连,w既为该边容量的下界同时也为该边容量的上界,即置low[u][v+n]=high[u][v+n]=w
可以将每列看成一个结点,每行看成一个结点,给每行,每列各建立一个节点。
设源点s与每个行节点连接(流量的上下界限制为每行的和),每个列节点与汇点t连接(流量的上下界限制为每列的和)。
从每个行节点流出col条边,流量的上下界从input的条件中获取,同理,每个列节点,有row条边流入。
这样如果存在最大流,一定是唯一的行和或列和,即符合条件限制。那么某行某列的两结点间的边的容量就是该行该列元素上下界容量(即元素的限制)之差。。这样最大流后确保满足题中行列和性质。再新建一个源点ss和汇点tt,那么ss到每个结点的边下界就是该结点入边下界容量和,各点到tt边的下界容量为该结点出边下界容量和。