题意:给你一个n*m的网格,每个网格里有一个整数,每次你可以选择任意一个点为起点开始跳,每次只能向右或者向下跳,长度任意,跳过的格子不能再跳,问你在K次之内是否能够恰好经过所有格子仅一次。
分析:带费用的最小K路径覆盖模型。这题关键在于K次限制的处理,的确很巧妙啊。我们将图建成二分图,将网格中每个点拆成两个点,X部正好n*m个点,Y部也正好n*m个点,设立源汇点S,T,先从S点出发,X部中的每个点建边add(x,y,1,0),然后Y部每个点向T建边,add(i+n*m,T,1,0),接下来就是比较巧妙的地方,在X部中加入一个点Q,从S点向Q建边add(S,Q,k,0)(容量为k,费用为0),然后Q点向Y部中每个点建边add(Q,i+n*m,1,0),最后对于网格中的每个点走向关系,在X部和Y部之间建边,边的权值为(两点之间的曼哈顿距离-1-可以得到的能量),最后跑最小费用最大流即可。感叹K次限制的建边处理。
代码:
//O(Kn^2m)
//如果要求最大费用的话 只需在加边的时候加-的边 输出时输出-ans即可
#pragma comment(linker,"/STACK:102400000,102400000")
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include