zoukankan      html  css  js  c++  java
  • POJ3436 ACM Computer Factory 网络流

      该题题义是这样的,有N台机器安排去组装电脑,每台电脑有P个零部件,一台可以出产的电脑必须要求每个部件都有。每台机器能够接受的本成品电脑不同,对于每个部件,输入数据给出了0(一定不能够在半成品上出现),1(一定要在上面出现),2(可以出现也可以不出现)。每台机器生产出来的半成品(或者成为了成品)的情况也有不同,对于每个部件0代表经过这个机器加工后,该号不见没有,相反,1代表有。

      由于每台机器的处理能力有限,所以这里要将点拆成边,点内的边赋值为产能,其他边均赋值为无穷大。对部件没有要求的机器为源点,对部件都有要求的机器为汇点。考虑好机器与机器之间的传递关系,建图后直接计算最大流,最后在遍历两两点之间的flow。

      代码如下:

    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #define SP 0
    #define T 2*N+1
    #define INF 0x3fffffff
    #define CP(x) (N+(x))
    #define MAXN 110
    using namespace std;
    
    int P, N, cap[MAXN][MAXN], flow[MAXN][MAXN];
    int c[MAXN], path[MAXN], MaxFlow;
    
    struct Node
    {
        int Q, S[15], D[15];
    }e[55];
    
    void init()
    {
        MaxFlow = 0;
        memset(cap, 0, sizeof (cap));
        memset(flow, 0, sizeof (flow));
    }
    
    bool Start(int x)
    {
        for (int i = 1; i <= P; ++i) {
            if (e[x].S[i] == 1) {
                return false;
            }
        }
        return true;
    }
    
    bool End(int x)
    {
        for (int i = 1; i <= P; ++i) {
            if (e[x].D[i] == 0) {
                return false;
            }
        }
        return true;
    }
    
    bool OK(int x, int y)
    {
        for (int i = 1; i <= P; ++i) {
            if (e[x].D[i] == 1 && (e[y].S[i] == 1 || e[y].S[i] == 2)) {
                continue;
            }
            else if (e[x].D[i] == 0 && (e[y].S[i] == 0 || e[y].S[i] == 2)) {
                continue;
            }
            else {
                return false;
            }
        }
        return true;
    }
    /*
    3 4
    15  0 0 0  0 1 0
    10  0 0 0  0 1 1
    30  0 1 2  1 1 1
    3   0 2 1  1 1 1
    */
    void bfs()
    {
        int pos;
        bool finish = false;
        while (!finish) {
            memset(c, 0, sizeof (c));
            queue<int>q;
            c[SP] = INF;
            q.push(SP);
            while (!q.empty()) {
                if (c[T]) {
                    break;
                }
                pos = q.front();
                q.pop();
                for (int i = 1; i <= T; ++i) {
                    if (!c[i] && cap[pos][i] > flow[pos][i]) { 
                        c[i] = min(c[pos], cap[pos][i]-flow[pos][i]);
                        q.push(i);
                        path[i] = pos;
                    }
                }   
            }
            if (c[T] == 0) {
                finish = true;
            }
            else {
                MaxFlow += c[T];
                pos = T;
                while (pos != SP) {
                    flow[path[pos]][pos] += c[T];
                    flow[pos][path[pos]] -= c[T];
                    pos = path[pos];
                }
            }
        }
    }
    
    void print()
    {
        int M = 0;
        for (int i = 1; i <= N; ++i) {
            for (int j = 1; j <= N; ++j) {
                if (flow[CP(i)][j] > 0) {
                    ++M;
                }
            }
        }
        printf("%d %d\n", MaxFlow, M);
        for (int i = 1; i <= N; ++i) {
            for (int j = 1; j <= N; ++j) {
                if (flow[CP(i)][j] > 0) {
                    printf("%d %d %d\n", i, j, flow[CP(i)][j]);
                }
            }
        } 
    }
    
    int main()
    {
        while (scanf("%d %d", &P, &N) == 2) {
            init();
            for (int i = 1; i <= N; ++i) {
                scanf("%d", &e[i].Q);
                for (int j = 1; j <= P; ++j) {
                    // 加工的条件
                    scanf("%d", &e[i].S[j]);
                }
                for (int j = 1; j <= P; ++j) {
                    // 出产的特性
                    scanf("%d", &e[i].D[j]);
                }
            }
            for (int i = 1; i <= N; ++i) {
                if (Start(i)) {
                    cap[SP][i] = INF;
                }
                if (End(i)) { 
                    cap[CP(i)][T] = INF;
                }
                cap[i][CP(i)] = e[i].Q;
                for (int j = 1; j <= N; ++j) {
                    if (OK(i, j)) {
                        cap[CP(i)][j] = INF;
                    }
                }
            }
            bfs();
            print();
        }
        return 0;
    }
  • 相关阅读:
    div拖拽缩放jquery插件编写——带8个控制点
    vuejs快速入门
    逗号运算笔记
    怎样用PHP制作验证码呢?
    mac下多个php版本快速切换的方法是怎么样
    HTML5 拖拽复制功能的实现方法
    CentOS下使用Percona XtraBackup对MySQL5.6数据库innodb和myisam的方法
    MySQL数据很大的时候
    Facebook MyRocks at MariaDB
    Mysql数据库知识-Mysql索引总结 mysql mysql数据库 mysql函数
  • 原文地址:https://www.cnblogs.com/Lyush/p/2574562.html
Copyright © 2011-2022 走看看