P4015 运输问题

 #include <bits/stdc++.h>
using namespace std;
const int maxn = , inf = 0x3f3f3f3f;
struct Edge {
int from, to, cap, flow, cost;
};
struct MCMF {
int n, m, s, t;
vector<Edge> edges;
vector<int> G[maxn];
int inq[maxn];
int d[maxn];
int p[maxn];
int a[maxn]; void init(int n) {
this->n = n;
for (int i = ; i <= n; ++i) G[i].clear();
edges.clear();
} void AddEdge(int from, int to, int cap, int cost) {
edges.push_back((Edge){from, to, cap, , cost});
edges.push_back((Edge){to, from, , , -cost});
m = edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
}
bool BellmanFord(int s, int t, int& flow, int& cost) {
for (int i = ; i <= n; ++i) d[i] = inf;
memset(inq, , sizeof(inq));
d[s] = ; inq[s] = ; p[s] = ; a[s] = inf; queue<int> que;
que.push(s);
while (!que.empty()) {
int u = que.front(); que.pop();
inq[u] = ;
for (int i = ; i < G[u].size(); ++i) {
Edge& e = edges[G[u][i]];
if (e.cap > e.flow && d[e.to] > d[u] + e.cost) {
d[e.to] = d[u] + e.cost;
p[e.to] = G[u][i];
a[e.to] = min(a[u], e.cap-e.flow);
if (!inq[e.to]) { que.push(e.to); inq[e.to] = ; }
}
}
}
if (d[t] == inf) return false;
flow += a[t];
cost += d[t] * a[t];
int u = t;
while (u != s) {
edges[p[u]].flow += a[t];
edges[p[u]^].flow -= a[t];
u = edges[p[u]].from;
}
return true;
}
int mincost(int s, int t) {
int flow = , cost = ;
while (BellmanFord(s, t, flow, cost));
return cost;
}
}mcmf;
int a[maxn], b[maxn], c[maxn][maxn];
int main() {
int m, n; scanf("%d%d",&m,&n);
int s = m+n+, t = m+n+; for (int i = ; i <= m; ++i) scanf("%d",&a[i]);
for (int j = ; j <= n; ++j) scanf("%d",&b[j]);
for (int i = ; i <= m; ++i) {
for (int j = ; j <= n; ++j) {
scanf("%d",&c[i][j]);
}
}
// 最小费用最大流
mcmf.init(n+m+);
for (int i = ; i <= m; ++i) {
mcmf.AddEdge(s,i,a[i],);
}
for (int i = ; i <= m; ++i) {
for (int j = ; j <= n; ++j) {
mcmf.AddEdge(i,j+m,inf,c[i][j]);
}
}
for (int j = ; j <= n; ++j) {
mcmf.AddEdge(j+m,t,b[j],);
}
printf("%d\n",mcmf.mincost(s,t)); // 最大费用最大流
mcmf.init(n+m+);
for (int i = ; i <= m; ++i) {
mcmf.AddEdge(s,i,a[i],);
}
for (int i = ; i <= m; ++i) {
for (int j = ; j <= n; ++j) {
mcmf.AddEdge(i,j+m,inf,-c[i][j]);
}
}
for (int j = ; j <= n; ++j) {
mcmf.AddEdge(j+m,t,b[j],);
}
printf("%d\n",-mcmf.mincost(s,t));
return ;
}
05-11 22:12