mirror of
https://github.com/Kiritow/OJ-Problems-Source.git
synced 2024-03-22 13:11:29 +08:00
115 lines
3.4 KiB
C++
115 lines
3.4 KiB
C++
|
#include <cstdio>
|
||
|
#include <cstring>
|
||
|
#include <algorithm>
|
||
|
#include <queue>
|
||
|
using namespace std;
|
||
|
const int N = 510;
|
||
|
const int M = 1000010;
|
||
|
const int INF = 0x7f7f7f7f;
|
||
|
struct Edge {
|
||
|
int v, cap, cost, next;
|
||
|
Edge() {}
|
||
|
Edge(int a, int b, int c, int d)
|
||
|
:v(a), cap(b), cost(c), next(d) {}
|
||
|
}e[M];
|
||
|
int head[N], sz;
|
||
|
int dis[N], pre[N], cur[N];
|
||
|
bool inq[N];
|
||
|
queue<int> q;
|
||
|
void graphinit() {
|
||
|
memset(head, -1, sizeof(head));
|
||
|
sz = 0;
|
||
|
}
|
||
|
void addedge(int u, int v, int cp, int ct) {
|
||
|
e[sz] = Edge(v, cp, ct, head[u]);
|
||
|
head[u] = sz++;
|
||
|
e[sz] = Edge(u, 0, -ct, head[v]);
|
||
|
head[v] = sz++;
|
||
|
}
|
||
|
pair<int, int> mcmf(int s, int t) {
|
||
|
int mc = 0, mf = 0;
|
||
|
while (true) {
|
||
|
memset(pre, -1, sizeof(pre));
|
||
|
memset(inq, 0, sizeof(inq));
|
||
|
memset(dis, 0x7f, sizeof(dis));
|
||
|
dis[s] = 0;
|
||
|
q.push(s);
|
||
|
while (!q.empty()) {
|
||
|
int u = q.front(); q.pop();
|
||
|
inq[u] = false;
|
||
|
for (int i = head[u]; i != -1; i = e[i].next) {
|
||
|
int v = e[i].v;
|
||
|
if (e[i].cap > 0 && dis[v] > dis[u] + e[i].cost) {
|
||
|
dis[v] = dis[u] + e[i].cost;
|
||
|
pre[v] = u; cur[v] = i;
|
||
|
if (!inq[v]) { inq[v] = true; q.push(v); }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (pre[t] == -1) break;
|
||
|
int aug = INF;
|
||
|
for (int i = t; i != s; i = pre[i])
|
||
|
aug = min(aug, e[cur[i]].cap);
|
||
|
mf += aug;
|
||
|
mc += dis[t] * aug;
|
||
|
for (int i = t; i != s; i = pre[i]) {
|
||
|
e[cur[i]].cap -= aug;
|
||
|
e[cur[i] ^ 1].cap += aug;
|
||
|
}
|
||
|
}
|
||
|
return make_pair(mf, mc);
|
||
|
}
|
||
|
const int MAXN = 110;
|
||
|
int n, m, k;
|
||
|
int candy_s[MAXN], candy_t[MAXN];
|
||
|
int start_time[MAXN][MAXN], start_cost[MAXN][MAXN];
|
||
|
int change_time[MAXN][MAXN], change_cost[MAXN][MAXN];
|
||
|
void read_matrix(int a[MAXN][MAXN], int n, int m) {
|
||
|
for (int i = 0; i < n; i++)
|
||
|
for (int j = 0; j < m; j++)
|
||
|
scanf("%d", &a[i][j]);
|
||
|
}
|
||
|
void work() {
|
||
|
for (int i = 0; i < n; i++)
|
||
|
scanf("%d%d", candy_s + i, candy_t + i);
|
||
|
read_matrix(start_time, n, m);
|
||
|
read_matrix(start_cost, n, m);
|
||
|
read_matrix(change_time, n, n);
|
||
|
read_matrix(change_cost, n, n);
|
||
|
graphinit();
|
||
|
int ss = 2 * n + m, tt = ss + 1;
|
||
|
for (int i = 0; i < n; i++)
|
||
|
addedge(ss, i, 1, 0);
|
||
|
for (int i = 0; i < m; i++)
|
||
|
addedge(i + n, tt, 1, 0);
|
||
|
for (int i = 0; i < n; i++)
|
||
|
addedge(i + n + m, tt, 1, 0);
|
||
|
for (int i = 0; i < n; i++)
|
||
|
for (int j = 0; j < m; j++) {
|
||
|
if (start_time[i][j] >= candy_t[i]) continue;
|
||
|
int cost = start_cost[i][j];
|
||
|
if (start_time[i][j] > candy_s[i])
|
||
|
cost += k * (start_time[i][j] - candy_s[i]);
|
||
|
addedge(i, j + n, 1, cost);
|
||
|
}
|
||
|
for (int i = 0; i < n; i++)
|
||
|
for (int j = 0; j < n; j++) if (i != j) {
|
||
|
int dt = candy_t[i] + change_time[i][j];
|
||
|
if (dt >= candy_t[j]) continue;
|
||
|
int cost = change_cost[i][j];
|
||
|
dt -= candy_s[j];
|
||
|
if (dt > 0)
|
||
|
cost += k * dt;
|
||
|
addedge(j, i + n + m, 1, cost);
|
||
|
}
|
||
|
pair<int, int> ans = mcmf(ss, tt);
|
||
|
if (ans.first < n) puts("-1");
|
||
|
else printf("%d\n", ans.second);
|
||
|
}
|
||
|
int main() {
|
||
|
while (scanf("%d%d%d", &n, &m, &k), n || m || k) {
|
||
|
work();
|
||
|
}
|
||
|
return 0;
|
||
|
}
|