题目描述
输入格式
输出格式
样例
数据范围与提示
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <vector>
using namespace std;
const int maxn = 1e2 + 7;
const int maxe = 200005;
const int INF = 0x3f3f3f3f;
int head[maxe], dis[maxn], path[maxn], pre[maxn], book[maxn] , n, m, s, t, k, sum;
int a[maxn], b[maxn], c[maxn][maxn];
struct node
{
int v, w, f, next, cnt;
}edge[maxe];
void addEdge(int u, int v, int f, int w)
{
edge[k].v = v;
edge[k].w = w;
edge[k].f = f;
edge[k].cnt = k;
edge[k].next = head[u];
head[u] = k++;
edge[k].v = u;
edge[k].w = -w;
edge[k].f = 0;
edge[k].cnt = k;
edge[k].next = head[v];
head[v] = k++;
}
void init()
{
s = 0, t = n+m+1, k = 0;
memset(head, -1, sizeof(head));
}
int spfa()
{
queue<int> q;
q.push(s);
memset(pre, -1, sizeof(pre));
memset(path, -1, sizeof(path));
for(int i = 1; i <= t; i++) dis[i] = INF;
dis[s] = 0;
memset(book, 0, sizeof(book));
book[s] = 1;
while(!q.empty())
{
int u = q.front();
q.pop();
book[u] = 0;
for(int i = head[u]; i != -1; i = edge[i].next)
{
int to = edge[i].v;
int w = edge[i].w;
int f = edge[i].f;
if(f && dis[to] > dis[u] + w)
{
dis[to] = dis[u] + w;
pre[to] = u;
path[to] = edge[i].cnt;
if(!book[to])
{
q.push(to);
book[to] = 1;
}
}
}
}
if(dis[t] != INF) return 1;
else return 0;
}
int Min_costflow()
{
int ans = 0;
int maxflow = 0;
while(spfa())
{
int minx = INF;
for(int i = t; i != s; i = pre[i])
{
minx = min(minx, edge[path[i]].f);
}
maxflow += minx;
ans += dis[t]*minx;
for(int i = t; i != s; i = pre[i])
{
edge[path[i]].f -= minx;
edge[path[i]^1].f += minx;
}
}
return ans;
}
int main()
{
while(~scanf("%d%d", &m, &n))
{
init();
int x, y, z;
for(int i = 1; i <= m; i++)
{
scanf("%d", &a[i]);
addEdge(s, i, a[i], 0);
}
for(int i = 1; i <= n; i++)
{
scanf("%d", &b[i]);
addEdge(i+m, t, b[i], 0);
}
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++)
{
scanf("%d", &c[i][j]);
addEdge(i, j+m, a[i], c[i][j]);
}
printf("%d\n", Min_costflow());
init();
for(int i = 1; i <= m; i++)
addEdge(s, i, a[i], 0);
for(int i = 1; i <= n; i++)
addEdge(i+m, t, b[i], 0);
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++)
addEdge(i, j+m, a[i], -c[i][j]);
printf("%d\n", -Min_costflow());
}
return 0;
}