zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    .NET使用DAO.NET实体类模型操作数据库
    .NET连接数据库及基本增删改查
    Struts2超链接
    微信小程序与Java后台的通信
    Java中重载和重写的区别
    Java中Double保留后小数位的几种方法
    北大集训2019游记
    HTML5前端
    软件测试面试题2018
    软件测试笔试题(2018精华篇)
  • 原文地址:https://www.cnblogs.com/Aragaki/p/10686095.html
Copyright © 2011-2022 走看看