P2050 [NOI2012]美食节 动态加边加点

修车数据加强版 需要动态加边加点

#include<bits/stdc++.h>
using namespace std;
const int INF = 0x7f7f7f7f;
const int MAXN = 100005, MAXM = 5000005;
int Head[MAXN], cur[MAXN], lev[MAXN], to[MAXM << 1], nxt[MAXM << 1], f[MAXM << 1], mono[MAXM << 1], ed = 1, S, T;
int pre[MAXN];
int t[105][105];
int n, m, sum, now;
bool exist[MAXN];
void addedge(int u, int v, int cap, int val) {
        to[++ed] = v;
        nxt[ed] = Head[u];
        Head[u] = ed;
        f[ed] = cap;
        mono[ed] = val;
        to[++ed] = u;
        nxt[ed] = Head[v];
        Head[v] = ed;
        f[ed] = 0;
        mono[ed] = -1 * val;
        return;
}
bool BFS() {
        int u;
        queue<int>q;
        memset(exist, false, sizeof(exist));
        memset(lev, 127, sizeof(lev));
        lev[S] = pre[S] = 0;
        q.push(S);
        while (q.size()) {
                u = q.front();
                q.pop();
                exist[u] = false;
                for (int i = Head[u]; i; i = nxt[i])
                        if (f[i] && lev[u] + mono[i] < lev[to[i]]) {
                                lev[to[i]] = lev[u] + mono[i];
                                pre[to[i]] = i;
                                if (!exist[to[i]]) {
                                        exist[to[i]] = true;
                                        q.push(to[i]);
                                }
                        }
        }
        memcpy(cur, Head, sizeof(Head));
        return lev[T] != INF;
}
int DFS(int u, int maxf) {
        if (u == T || !maxf) {
                return maxf;
        }
        exist[u] = true;
        int cnt = 0;
        for (int &i = cur[u], tem; i; i = nxt[i])
                if (f[i] && lev[u] + mono[i] == lev[to[i]]) {
                        if (exist[to[i]]) {
                                continue;
                        }
                        tem = DFS(to[i], min(f[i], maxf));
                        maxf -= tem;
                        f[i] -= tem;
                        f[i ^ 1] += tem;
                        cnt += tem;
                        if (!maxf) {
                                break;
                        }
                }
        if (!cnt) {
                lev[u] = -1 * INF;
        }
        exist[u] = false;
        return cnt;
}
int Augment() {
        int delta = INF;
        for (int i = pre[T]; i; i = pre[to[i ^ 1]])
                if (f[i] < delta) {
                        delta = f[i];
                }
        for (int i = pre[T]; i; i = pre[to[i ^ 1]]) {
                f[i] -= delta;
                f[i ^ 1] += delta;
        }
        return delta * lev[T];
}
int MCMF() {
        int ans = 0;
        memset(exist, false, sizeof(exist));
        while (BFS())
                //ans+=DFS(S,INF)*lev[T];
        {
                int j = to[pre[T] ^ 1];
                addedge(j + 1, T, 1, 0);
                j++;
                for (int i = 1; i <= n; i++) {
                        int x = (j - n - 1) / sum + 1;
                        int y = j - n - (x - 1) * sum;
                        addedge(i, j, 1, y * t[x][i]);
                }
                ans += Augment();
        }
        return ans;
}
int main() {
        sum = 0;
        scanf("%d %d", &n, &m);
        S = 0;
        for (int i = 1; i <= n; i++) {
                scanf("%d", &now);
                sum += now;
                addedge(S, i, now, 0);
        }
        T = n + sum * m + 1;
        for (int i = n + 1; i <= T - 1; i += sum) {
                addedge(i, T, 1, 0);
        }
        for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= m; j++) {
                        scanf("%d", &t[j][i]);
                }
        }
        for (int i = 1; i <= n; i++) {
                for (int j = n + 1; j <= T - 1; j += sum) {
                        int x = (j - n - 1) / sum + 1;
                        int y = j - n - (x - 1) * sum;
                        addedge(i, j, 1, y * t[x][i]);
                }
        }
        int ans = MCMF();
        cout << ans << endl;
        return 0;
}
View Code
原文地址:https://www.cnblogs.com/Aragaki/p/10686095.html