您的位置:首页 > 其它

[CODEVS1914] 运输问题(最小费用最大流)

2017-06-14 11:14 393 查看

传送门

 

水题。

建图都不想说了

 

——代码

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define INF 1e9
#define M 101
#define N 100001
#define min(x, y) ((x) < (y) ? (x) : (y))

int n, m, cnt, s, t;
int a[M], b[M], map[M][M], dis
, pre
;
int head
, to[N << 1], val[N << 1], cost[N << 1], next[N << 1];
bool vis
;

inline int read()
{
int x = 0, f = 1;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
return x * f;
}

inline void add(int x, int y, int z, int c)
{
to[cnt] = y;
val[cnt] = z;
cost[cnt] = c;
next[cnt] = head[x];
head[x] = cnt++;
}

inline bool spfa()
{
int i, u, v;
std::queue <int> q;
memset(vis, 0, sizeof(vis));
memset(pre, -1, sizeof(pre));
memset(dis, 127 / 3, sizeof(dis));
q.push(s);
dis[s] = 0;
while(!q.empty())
{
u = q.front(), q.pop();
vis[u] = 0;
for(i = head[u]; i ^ -1; i = next[i])
{
v = to[i];
if(val[i] && dis[v] > dis[u] + cost[i])
{
dis[v] = dis[u] + cost[i];
pre[v] = i;
if(!vis[v])
{
q.push(v);
vis[v] = 1;
}
}
}
}
return pre[t] ^ -1;
}

inline int dinic()
{
int i, d, sum = 0;
while(spfa())
{
d = 1e9;
for(i = pre[t]; i ^ -1; i = pre[to[i ^ 1]]) d = min(d, val[i]);
for(i = pre[t]; i ^ -1; i = pre[to[i ^ 1]])
{
val[i] -= d;
val[i ^ 1] += d;
}
sum += dis[t] * d;
}
return sum;
}

int main()
{
int i, j;
m = read();
n = read();
s = 0, t = n + m + 1;
memset(head, -1, sizeof(head));
for(i = 1; i <= m; i++)
{
a[i] = read();
add(s, i, a[i], 0);
add(i, s, 0, 0);
}
for(i = 1; i <= n; i++)
{
b[i] = read();
add(i + m, t, b[i], 0);
add(t, i + m, 0, 0);
}
for(i = 1; i <= m; i++)
for(j = 1; j <= n; j++)
{
map[i][j] = read();
add(i, j + m, INF, map[i][j]);
add(j + m, i, 0, -map[i][j]);
}
printf("%d\n", dinic());
cnt = 0;
memset(head, -1, sizeof(head));
for(i = 1; i <= m; i++)
{
add(s, i, a[i], 0);
add(i, s, 0, 0);
}
for(i = 1; i <= n; i++)
{
add(i + m, t, b[i], 0);
add(t, i + m, 0, 0);
}
for(i = 1; i <= m; i++)
for(j = 1; j <= n; j++)
{
add(i, j + m, INF, -map[i][j]);
add(j + m, i, 0, map[i][j]);
}
printf("%d\n", -dinic());
return 0;
}
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: