首先是二分图匹配的代码 把等待时间设置为负值 求最大匹配
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#define SF scanf
#define PF printf
#define min(x, y) ((x) < (y) ? (x) : (y))
using namespace std;
typedef long long LL;
const int MAXN = 9;
const int MAXM = 60;
const int INF = 0x3f3f3f3f;
int n, m;
struct Node {
int v, wt;
Node () {}
Node (int a, int b) : v(a), wt(b) {}
} ;
template <int maxn>
struct K_M {
int n, m;
vector <Node> G[maxn+10];
int Lx[maxn+10], Ly[maxn+10], slack[maxn+10], Left[maxn+10];
bool S[maxn+10], T[maxn+10];
void add(int u, int v, int wt) { G[u].push_back(Node(v, wt)); }
int Match(int u) {
S[u] = true;
for(int i = 0; i < G[u].size(); i++) {
int v = G[u][i].v, wt = G[u][i].wt;
if(Lx[u] + Ly[v] == wt && !T[v]) {
T[v] = true;
if(!Left[v] || Match(Left[v])) {
Left[v] = u;
return 1;
}
}
slack[v] = min(Lx[u] + Ly[v] - wt, slack[v]);
}
return 0;
}
void Update() {
int a = INF;
for(int i = 1; i <= m; i++) if(!T[i]) a = min(a, slack[i]);
for(int i = 1; i <= n; i++) if(S[i]) Lx[i] -= a;
for(int i = 1; i <= m; i++)
if(T[i]) Ly[i] += a;
else slack[i] -= a;
}
int BestMatch(int _n, int _m) {
int ans = 0;
n = _n; m = _m;
for(int i = 1; i <= n; i++) {
memset(slack, 0x3f, sizeof(slack));
while(true) {
memset(S, 0, sizeof(S));
memset(T, 0, sizeof(T));
if(Match(i)) break;
else Update();
}
}
for(int i = 1; i <= m; i++) ans += Lx[Left[i]] + Ly[i];
return -ans;
}
};
K_M <MAXN * MAXM> KM;
int main()
{
SF("%d%d", &m, &n);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) {
int x; SF("%d", &x);
for(int k = 1; k <= n; k++)
KM.add(i, (j-1) * n + k, -x * k);
}
int ans = KM.BestMatch(n, n*m);
PF("%.2f", 1.0 * ans / n);
}
费用流代码
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#define SF scanf
#define PF printf
using namespace std;
typedef long long LL;
const int MAXN = 1000;
const int INF = 0x3f3f3f3f;
int n, m, S, T, k;
int t[100][100];
struct Node {
int u, v, c, cost;
Node () {}
Node (int a, int b, int C, int d) : u(a), v(b), c(C), cost(d) {}
} ;
template <int maxn>
struct MCMF {
int n, m, s, t;
vector <Node> Edge;
vector <int> G[maxn+10];
int inq[maxn+10], a[maxn+10], p[maxn+10], d[maxn+10];
void add(int u, int v, int c, int wt) {
Edge.push_back(Node(u, v, c, wt));
Edge.push_back(Node(v, u, 0, -wt));
m = Edge.size();
G[u].push_back(m-2); G[v].push_back(m-1);
}
bool SPFA(int s, int t, int &Flow, int &Cost) {
queue <int> q;
memset(d, 0x3f, sizeof(d));
for(int i = 1; i <= t; i++) inq[i] = 0;
d[s] = 0; a[s] = INF; p[s] = 0; inq[s] = 1;
q.push(s);
while(!q.empty()) {
int u = q.front(); q.pop();
inq[u] = 0;
for(int i = 0; i < G[u].size(); i++) {
Node &e = Edge[G[u][i]];
int v = e.v, c = e.c, wt = e.cost;
if(c && d[v] > d[u] + wt) {
d[v] = d[u] + wt;
a[v] = min(a[u], c);
p[v] = G[u][i];
if(!inq[v]) inq[v] = true, q.push(v);
}
}
}
if(d[t] == INF) return false;
Flow += a[t];
Cost += d[t];
int u = t;
while(u != s) {
Edge[p[u]].c -= a[t];
Edge[p[u]^1].c += a[t];
u = Edge[p[u]].u;
}
return true;
}
int Mincost (int s, int t) {
int Flow = 0, Cost = 0;
while(SPFA(s, t, Flow, Cost))
;
return Cost;
}
} ;
MCMF <MAXN> sap;
int main()
{
SF("%d%d", &m, &n);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
SF("%d", &t[i][j]);
S = n + n * m + 1; T = S + 1;
sap.n = T;
for(int i = 1; i <= n; i++) sap.add(S, i, 1, 0);
for(int i = n+1; i <= n+n*m; i++) sap.add(i, T, 1, 0);
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++)
for(int k = 1; k <= n; k++)
sap.add(k, n+n*(i-1)+j, 1, t[k][i] * j);
int ans = sap.Mincost(S, T);
PF("%.2f", 1.0*ans/n);
}