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
| #include <cstdio> #include <queue> #include <cstring> #define int long long
const int INF = 1e18; inline int abs(int k) {return k >= 0 ? k : -k;} inline int min(const int x, const int y) {return x < y ? x : y;} struct Edge { int to, cap, cost, nxt; } e[4000005]; int head[10005], cur[10005], dis[10005], Maxflow, Maxcost; int rx[1005], ry[1005], rc[1005], bx[1005], by[1005], bc[1005]; int tot = 1, s, t; bool vis[10005], mark[10005]; std::queue<int> Q; inline void AddEdge(int u, int v, int cap, 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() { memcpy(cur, head, sizeof cur); memset(vis, 0, sizeof vis); memset(dis, ~0x3f, sizeof dis); memset(mark, 0, sizeof mark); Q.push(s); dis[s] = 0; 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(int u, int flow) { if (u == t) return flow; vis[u] = true; int used = 0, tmp; for (int i = cur[u]; i && used <= flow; i = e[i].nxt) { cur[u] = i; if (e[i].cap && dis[u] + e[i].cost == dis[e[i].to]) { int v = e[i].to; if (!vis[v] && (tmp = dfs(v, min(flow - used, e[i].cap)))) used += tmp, e[i].cap -= tmp, e[i ^ 1].cap += tmp; } } return used; }
void Dinic() { int flow; while (SPFA()) Maxflow += (flow = dfs(s, INF)), Maxcost += flow * dis[t]; }
signed main() { int n; scanf("%lld", &n); s = 0, t = 2 * n + 5; int a = 2 * n + 1, b = 2 * n + 2, c = 2 * n + 3, d = 2 * n + 4; for (int i = 1; i <= n; ++ i) scanf("%lld%lld%lld", rx + i, ry + i, rc + i); for (int i = 1; i <= n; ++ i) scanf("%lld%lld%lld", bx + i, by + i, bc + i); for (int i = 1; i <= n; ++ i) { AddEdge(s, i, rc[i], 0); AddEdge(i, a, INF, -rx[i] - ry[i]); AddEdge(i, b, INF, -rx[i] + ry[i]); AddEdge(i, c, INF, rx[i] - ry[i]); AddEdge(i, d, INF, rx[i] + ry[i]); } for (int i = 1; i <= n; ++ i) { AddEdge(i + n, t, bc[i], 0); AddEdge(a, i + n, INF, bx[i] + by[i]); AddEdge(b, i + n, INF, bx[i] - by[i]); AddEdge(c, i + n, INF, by[i] - bx[i]); AddEdge(d, i + n, INF, -bx[i] - by[i]); } Dinic(); printf("%lld", Maxcost); }
|