# Minimum Cost [poj-2516] [maximum flow Minimum Cost template topic]

There are N merchants who need the source of goods, m cargo suppliers, N merchants who need K kinds of goods, and each kind of goods has its corresponding demand. Each kind of goods of M merchants is the corresponding inventory, and then the k N*M matrix represents the price of K goods delivered from the supplier to the merchant's unit, which is the standard maximum flow minimum cost. We just need to establish For such an edge, for all suppliers, the size of the stream established with the source point is the number of sides they own, and the cost of establishing an infinite edge with the merchant is the cost of the unit stream, and then the merchant starts from the merchant to the sink point to establish the size of the stream as the required edge, and the cost of establishing the edge with the sink point and the source point is 0.

```#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int S = 0;
const int maxN = 107;
int N, M, K, T, r[maxN][maxN], cost[maxN][maxN];
struct node
{
int thing[maxN];
}a[maxN<<1];
int pre[maxN], dist[maxN], Flow[maxN];  bool inque[maxN];
queue<int> Q;
bool spfa()
{
memset(pre, -1, sizeof(pre));   memset(inque, false, sizeof(inque));    memset(dist, INF, sizeof(dist));    memset(Flow, 0, sizeof(Flow));
while(!Q.empty()) Q.pop();  Q.push(S);  inque[S] = true;    dist[S] = 0;    Flow[S] = INF;
while(!Q.empty())
{
int u = Q.front();  Q.pop();    inque[u] = false;
for(int i=1; i <= T; i++)
{
if(r[u][i] && dist[i] > dist[u] + cost[u][i])
{
dist[i] = dist[u] + cost[u][i];
pre[i] = u;
Flow[i] = min(Flow[u], r[u][i]);
if(!inque[i])
{
Q.push(i);
inque[i] = true;
}
}
}
}
return pre[T] ^ -1;
}
int main()
{
while(scanf("%d%d%d", &N, &M, &K) && (N || M || K))
{
T = N + M + 1;  memset(r, 0, sizeof(r));
for(int i=1; i<=N; i++) for(int j=1; j<=K; j++) scanf("%d", &a[i].thing[j]);
for(int i=1; i<=M; i++) for(int j=1; j<=K; j++) scanf("%d", &a[i+N].thing[j]);
bool flag = true;
for(int ki=1; ki<=K; ki++)
{
int sum1 = 0, sum2 = 0; //Demand, ownership
for(int i=1; i<=N; i++) sum1 += a[i].thing[ki];
for(int i=1; i<=M; i++) sum2 += a[N+i].thing[ki];
if(sum1 > sum2)
{
flag = false;
break;
}
}
int ans = 0;
for(int ki=1; ki<=K; ki++)
{
memset(r, 0, sizeof(r));
memset(cost, 0, sizeof(cost));
for(int i=1; i<=N; i++)
{
r[i][T] = a[i].thing[ki];  r[T][i] = 0;
for(int j=1; j<=M; j++)
{
scanf("%d", &cost[j+N][i]);
cost[i][j+N] = -cost[j+N][i];
r[j+N][i] = INF;
}
}
for(int i=1; i<=M; i++) r[S][i+N] = a[i+N].thing[ki];
if(!flag) continue;
while(spfa())
{
int now = T, last = pre[now];
while(now)
{
r[last][now] -= Flow[T];
r[now][last] += Flow[T];
now = last;
last = pre[now];
}
ans += dist[T] * Flow[T];
}
}
printf("%d\n", flag ? ans : -1);
}
return 0;
}
```

Posted by Rigo on Sun, 01 Dec 2019 12:19:13 -0800