求调费用瘤
查看原帖
求调费用瘤
461426
CmsMartin楼主2022/9/12 15:31

由于原贴是和某个猴子的对线帖,所以重发。

30pts,不知道错哪了。Record\mathcal{Record}

#include <bits/stdc++.h>
using namespace std;
const long long MAXN = 1e5 + 10, MAXM = 1e6 + 10, INF = 0x3f3f3f3f3f3f3f3f;
long long N, p, m, f, n, s;
struct _ {
    int To, Next;
	long long Flow, Cost;
} G[MAXN];
int Head[MAXN], Cnt = 1;
void _add(int u, int v, long long w, long long c) {
    G[++Cnt] = {v, Head[u], w, c};
    Head[u] = Cnt;
}
void Add(int u, int v, long long w, long long c) {
    _add(u, v, w, c);
    _add(v, u, 0, -c);
}
long long Dist[MAXN], Pre[MAXN], Incf[MAXN];
bool Vis[MAXN];
long long T, S;
bool SPFA() {
    memset(Dist, 0x3f, sizeof Dist);
    queue<int> q;
    q.push(S);
    Dist[S] = 0;
    Vis[S] = true;
    Incf[S] = INF;
    Incf[T] = 0;

    while (q.size()) {
        int u = q.front();
        q.pop();
        Vis[u] = false;

        for (int i = Head[u]; i; i = G[i].Next) {
            const auto &v = G[i].To;
			const auto &w = G[i].Flow;
			const auto &c = G[i].Cost;

            if (!w || Dist[v] <= Dist[u] + c)
                continue;

            Dist[v] = Dist[u] + c;
            Incf[v] = min(w, Incf[u]);
            Pre[v] = i;

            if (!Vis[v]) {
                q.push(v);
                Vis[v] = true;
            }
        }
    }
    return Dist[T] != INF;
}
long long MaxFlow, MinCost;
void UpDate() {
    MaxFlow += Incf[T];

    for (int u = T; u != S; u = G[Pre[u] ^ 1].To) {
        G[Pre[u]].Flow -= Incf[T];
        G[Pre[u] ^ 1].Flow += Incf[T];
        MinCost += Incf[T] * G[Pre[u]].Cost;
    }
}
void MCMF() {
    while (SPFA()) {
    	UpDate();
	}
}

int main() {
    scanf("%lld", &N);
    S = 0;
    T = N * 2 + 1;

    for (int i = 1, x; i <= N; i++) {
        scanf("%lld", &x);
        Add(S, i, x, 0);
        Add(i + N, T, x, 0);
    }

    cin >> p >> m >> f >> n >> s;

    for (int i = 1; i <= N; i++) {
        Add(S, i + N, INF, p);

        if (i < N)
            Add(i, i + 1, INF, 0);

        if (i + m <= N)
            Add(i, i + N + m, INF, f);

        if (i + n <= N)
            Add(i, i + N + f, INF, s);
    }

    MCMF();
    cout << MinCost << endl;
    return 0;
}
2022/9/12 15:31
加载中...