• POJ-3436 ACM Computer Factory(最大流,流量方案)


    题目链接:POJ-3436 ACM Computer Factory

    题意

    电脑工厂有$N$个机器,第$i$个机器单位时间产量为$Q_i$。每台电脑由$P$个部件组成,每个机器工作时只能把有某些部件的半成品电脑(或什么都没有的空电脑)变成有另一些部件的半成品电脑或完整电脑(也可能移除某些部件)。求电脑公司的单位时间最大产量,以及哪些机器有协作关系,即哪些机器把它的多少件产品交给哪些机器加工。


    思路

    流网络建图如下:

    • 添加一个源点$s$,$s$提供最初的原料 00000...;
    • 添加一个汇点$t$,$t$接受最终的产品 11111...;
    • 将每个机器拆成两个点: 接收结点$u$和产出结点$v$,连边$(u,v,Q_i)$;
    • $s$连边到所有接收 "0000..." 或 "若干个0及若干个2" 的接收结点,容量为无穷大;
    • 产出节点连边到能接受其产品的其他机器的接收结点,容量为无穷大;
    • 能产出成品的产出结点,连边到T,容量无穷大。

    最大流就是这$N$个机器单位时间产出成品的最大数量。

    增加一个数组在求最大流过程中记录每条边的流量变动即可处理出流量方案,机器$u$的产出结点和机器$v$的接收结点之间的流量$f$就表示机器$u$要把产出的$f$件产品交给机器$v$处理。


    代码实现

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using std::queue;
    const int INF = 1 << 29, N = 110, M = 11000;
    int head[N], d[N], in[N][25], F[N][N];
    int s, t, tot, maxflow;
    struct Edge
    {
        int to, cap, nex;
    } edge[M];
    queue<int> q;
    void add(int x, int y, int z) {
        edge[++tot].to = y, edge[tot].cap = z, edge[tot].nex = head[x], head[x] = tot;
        edge[++tot].to = x, edge[tot].cap = 0, edge[tot].nex = head[y], head[y] = tot;
    }
    bool bfs() {
        memset(d, 0, sizeof(d));
        while (q.size()) q.pop();
        q.push(s); d[s] = 1;
        while (q.size()) {
            int x = q.front(); q.pop();
            for (int i = head[x]; i; i = edge[i].nex) {
                int v = edge[i].to;
                if (edge[i].cap && !d[v]) {
                    q.push(v);
                    d[v] = d[x] + 1;
                    if (v == t) return true;
                }
            }
        }
        return false;
    }
    int dinic(int x, int flow) {
        if (x == t) return flow;
        int rest = flow, k;
        for (int i = head[x]; i && rest; i = edge[i].nex) {
            int v = edge[i].to;
            if (edge[i].cap && d[v] == d[x] + 1) {
                k = dinic(v, std::min(rest, edge[i].cap));
                if (!k) d[v] = 0;
                edge[i].cap -= k;
                edge[i^1].cap += k;
                rest -= k;
                F[x][v] += k;
                F[v][x] -= k;
            }
        }
        return flow - rest;
    }
    void init(int n) {
        memset(head, 0, sizeof(head));
        memset(F, 0, sizeof(F));
        s = 0, t = 2 * n + 1, tot = 1, maxflow = 0;
    }
    
    
    int main() {
        int p, n;
        while (~scanf("%d %d", &p, &n)) {
            init(n);
            for (int i = 0; i <= 2 * p; i++) {
                in[0][i] = 0;
                in[2*n+1][i] = 1;
            }
            for (int i = 1; i <= n; i++) {
                for (int j = 0; j <= 2 * p; j++) {
                    scanf("%d", &in[i][j]);
                }
                add(i, i + n, in[i][0]);
            }
            for (int i = 0; i <= n; i++) {
                for (int j = 1; j <= 2 * n + 1; j++) {
                    if (j == n + 1) { j = 2 * n; continue; }
                    if (i == j) continue;
                    bool flag = true;
                    for (int k = 1; k <= p; k++) {
                        if (in[j][k] != 2 && in[i][k+p] != in[j][k]) {
                            flag = false;
                            break;
                        }
                    }
                    if (!flag) continue;
                    if (i == s) add(s, j, in[j][0]);
                    else if (j == t) add(i + n, t, in[i][0]);
                    else add(i + n, j, std::min(in[i][0], in[j][0]));
                }
            }
            while (bfs()) maxflow += dinic(s, INF);
            printf("%d ", maxflow);
            int cnt = 0;
            for (int i = n + 1; i <= 2 * n; i++) {
                for (int j = 1; j <= n; j++) {
                    if (F[i][j] > 0) cnt++;
                }
            }
            printf("%d
    ", cnt);
            for (int i = n + 1; i <= 2 * n; i++) {
                for (int j = 1; j <= n; j++) {
                    if (F[i][j] > 0) printf("%d %d %d
    ", i - n, j, F[i][j]);
                }
            }
        }
        return 0;
    }
    View Code
    作者:_kangkang
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    SpringMVC中web.xml中url配置路径 / 和 /* 的区别
    spring mvc @RequestMapping method 不写的话,默认GET、POST都支持,根据前端方式自动适应
    MyBatis项目所引用的一切依赖jar包和自定义设置
    Python 代码性能优化技巧
    linux basic commands
    linuxx virutal machine installation
    安装 Django
    virtualenv (isolated virtual environment) for python runtime
    夜间模式的开启与关闭,父模板的制作
    完成登录与注册页面的前端
  • 原文地址:https://www.cnblogs.com/kangkang-/p/11342798.html
Copyright © 2020-2023  润新知