考虑费用流。拆点行列模型,枚举总共选的个数 k k k,理解成从小到大选匹配的 k k k个横坐标和 k k k个纵坐标。额外增加 k k k个对应选择横坐标的点和 k k k个对应选择纵坐标的点,我们可以将 m m m个限制转化为对这 2 k 2k 2k个点选择范围的限制,这样可以得到一个点数为 O ( N + k ) \mathcal O(N+k) O(N+k),边数为 O ( N k ) \mathcal O(Nk) O(Nk)的图,对它跑费用流即可。
因为流量是 O ( k ) O(k) O(k)的,一个宽松的时间复杂度上界为 O ( N 5 ) O(N^5) O(N5)(要跑 N N N遍)。有一个上下界费用流的建图也可以做。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
struct Edge {
int t,f,next;
ll v;
Edge() {
}
Edge(int a,int b,ll c,int d):t(a),f(b),v(c),next(d) {
}
};
Edge e[1000000];
int head[410],vs,vt,tot=-1;
void addEdge(int x,int y,int z,ll v) {
e[++tot]=Edge(y,z,v,head[x]);
head[x]=tot;
e[++tot]=Edge(x,0,-v,head[y]);
head[y