1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| #include <cstdio> #include <queue> #include <cstring> #include <cstdlib>
inline int min(const int x, const int y) {return x < y ? x : y;} const int INF = 1e9; struct Node {int x, y;}; struct Edge { int to, nxt, cap, cost; } e[100005]; int head[505], dis[505], cur[505], f[205][205], tme[205][205], tot = 1, s, t; int a[205], b[205], S[205], T[205], c[205]; bool mark[505], vis[505]; std::queue<int> Q; inline void AddEdge(const int u, const int v, const int cap, const int cost) { e[++ tot].to = v, e[tot].nxt = head[u], head[u] = tot; e[tot].cap = cap, e[tot].cost = cost; e[++ tot].to = u, e[tot].nxt = head[v], head[v] = tot; e[tot].cap = 0, e[tot].cost = -cost; }
bool SPFA() { memset(vis, 0, sizeof vis); memset(dis, 0x3f, sizeof dis); memset(mark, 0, sizeof mark); memcpy(cur, head, sizeof cur); dis[s] = 0; Q.push(s); while (Q.size()) { int u(Q.front()); Q.pop(); mark[u] = false; for (int i(head[u]); i; i = e[i].nxt) { int v(e[i].to); if (e[i].cap && dis[u] + e[i].cost < dis[v]) { dis[v] = dis[u] + e[i].cost; if (!mark[v]) Q.push(v), mark[v] = true; } } } return dis[t] < INF; }
int dfs(const int u, const int flow) { if (u == t) return flow; vis[u] = true; int tmp(0), used(0); for (int i(cur[u]); i; i = e[i].nxt) { cur[u] = i; if (e[i].cap && dis[u] + e[i].cost == dis[e[i].to] && !vis[e[i].to]) { int v(e[i].to); if (tmp = dfs(v, min(flow - used, e[i].cap))) { e[i].cap -= tmp, e[i ^ 1].cap += tmp, used += tmp; if (used == flow) return used; } } } if (!used) dis[u] = 0; return used; }
int Dinic() { int Mincost(0); while (SPFA()) Mincost += dis[t] * dfs(s, INF); return Mincost; }
int main() { int n, m, k, ed; scanf("%d%d%d%d", &n, &m, &k, &ed); for (int i(1); i <= n; ++ i) for (int j(1); j <= n; ++ j) scanf("%d", &tme[i][j]); for (int i(1); i <= n; ++ i) for (int j(1); j <= n; ++ j) scanf("%d", &f[i][j]); for (int i(1); i <= m; ++ i) scanf("%d%d%d%d%d", a + i, b + i, S + i, T + i, c + i), ++ a[i], ++ b[i]; s = 0, t = 2 * m + 2; for (int i(1); i <= m; ++ i) { AddEdge(i + 1, i + m + 1, 1, -c[i]); if (tme[1][a[i]] <= S[i]) AddEdge(1, i + 1, 1, f[1][a[i]]); if (T[i] + tme[b[i]][1] <= ed) AddEdge(i + 1 + m, t, 1, f[b[i]][1]); for (int j(1); j <= m; ++ j) if (i != j && T[i] + tme[b[i]][a[j]] <= S[j]) AddEdge(i + m + 1, j + 1, 1, f[b[i]][a[j]]); } AddEdge(0, 1, k, 0); printf("%d", -Dinic()); return 0; }
|