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
| #include <cstdio> #include <queue> #include <cstring> #define int long long
const int INF = 1e9; inline int min(const int x, const int y) {return x < y ? x : y;} struct Edge { int to, nxt, cap, cost; } e[200005]; int head[50005], cur[50005], dis[50005], s, t, tot = 1, N; bool mark[50005], vis[50005]; 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() { memcpy(cur, head, sizeof cur); memset(mark, 0, sizeof mark); memset(dis, 0x3f, sizeof dis); memset(vis, 0, sizeof vis); 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 used(0), tmp(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]) { tmp = dfs(e[i].to, 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 Maxflow(0), Mincost(0), flow(0); while (SPFA()) Maxflow += (flow = dfs(s, INF)), Mincost += flow * dis[t]; return Mincost; }
signed main() { int p, m, f, n, s; scanf("%lld", &N); s = 0, t = 2 * N + 1; for (int i(1); i <= N; ++ i) { int x; scanf("%lld", &x); AddEdge(0, i + N, x, 0); AddEdge(i, t, x, 0); } scanf("%lld%lld%lld%lld%lld", &p, &m, &f, &n, &s); for (int i(1); i <= N; ++ i) { AddEdge(0, i, INF, p); if (i < N) AddEdge(i + N, i + N + 1, INF, 0); if (i + m <= N) AddEdge(i + N, i + m, INF, f); if (i + n <= N) AddEdge(i + N, i + n, INF, s); } printf("%lld", Dinic()); return 0; }
|