zoukankan      html  css  js  c++  java
  • POJ 3436 ACM Computer Factory

    Description:

    As you know, all the computers used for ACM contests must be identical, so the participants compete on equal terms. That is why all these computers are historically produced at the same factory.

    Every ACM computer consists of P parts. When all these parts are present, the computer is ready and can be shipped to one of the numerous ACM contests.

    Computer manufacturing is fully automated by using N various machines. Each machine removes some parts from a half-finished computer and adds some new parts (removing of parts is sometimes necessary as the parts cannot be added to a computer in arbitrary order). Each machine is described by its performance (measured in computers per hour), input and output specification.

    Input specification describes which parts must be present in a half-finished computer for the machine to be able to operate on it. The specification is a set of P numbers 0, 1 or 2 (one number for each part), where 0 means that corresponding part must not be present, 1 — the part is required, 2 — presence of the part doesn't matter.

    Output specification describes the result of the operation, and is a set of P numbers 0 or 1, where 0 means that the part is absent, 1 — the part is present.

    The machines are connected by very fast production lines so that delivery time is negligibly small compared to production time.

    After many years of operation the overall performance of the ACM Computer Factory became insufficient for satisfying the growing contest needs. That is why ACM directorate decided to upgrade the factory.

    As different machines were installed in different time periods, they were often not optimally connected to the existing factory machines. It was noted that the easiest way to upgrade the factory is to rearrange production lines. ACM directorate decided to entrust you with solving this problem.

    Input:

    Input file contains integers PN, then N descriptions of the machines. The description of ith machine is represented as by 2 P + 1 integersQiSi,1Si,2...Si,PDi,1Di,2...Di,P, where Qi specifies performance, Si,j — input specification for part j, Di,k — output specification for part k.

    Constraints:

    1 ≤ P ≤ 10, 1 ≤ N ≤ 50, 1 ≤ Qi ≤ 10000

    Output:

    Output the maximum possible overall performance, then M — number of connections that must be made, then M descriptions of the connections. Each connection between machines A and B must be described by three positive numbers ABW, where W is the number of computers delivered from A to B per hour.

    If several solutions exist, output any of them.

    Sample Input:

    Sample input 1 
    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
    Sample input 2
    3 5 5 0 0 0 0 1 0 100 0 1 0 1 0 1 3 0 1 0 1 1 0 1 1 0 1 1 1 0 300 1 1 2 1 1 1
    Sample input 3
    2 2 100 0 0 1 0 200 0 1 1 1

    Sample Output

    Sample output 1 
    25 2 1 3 15 2 3 10
    Sample output 2
    4 5 1 3 3 3 5 3 1 2 1 2 4 1 4 5 1
    Sample output 3
    0 0
    题意:有一个ACM工厂会生产一些电脑,在这个工厂里面有一些生产线,分别生产不同的零件,不过他们生产的电脑可能是一体机,所以只能一些零件加工后别的生产线才可以继续加工,比如产品A在生产线1号加工后继续前往生产线2号继续加工,直到成为完全产品。输入 P 意思是这个电脑需要P个零件,N表示有N个生产线,每个生产线都有最大加工量,并且需要什么零件和输出的是什么零件,0表示没有这个零件,1表示有这个零件,2表示有没有都可以。

    最大流问题:求出最大流后,在剩余网络中比较与刚开始的权值大小,输出权值变小的路径及变小的权值即可。

    具体题解:http://www.cnblogs.com/liuxin13/p/4711704.html
    #include<stdio.h>
    #include<queue>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    const int N=110;
    
    struct node
    {
        int in[N], out[N], perform; ///存放的分别是接受的零件,输出的零件,该生产线最大生产量
    }no[N];
    struct Per
    {
        int x, y, per; ///存放的分别是输出零件的的生产线,接受零件的生产线,输出零件的生产线的生产量
    }pe[N];
    int G[N][N], g[N][N], layer[N], m, n;
    
    void Init()
    {
        int i;
    
        memset(g, 0, sizeof(g));
        memset(G, 0, sizeof(G));
    
        for (i = 1; i <= m; i++)
        {
            no[1].out[i] = 0; ///从源点输出的零件是无限制零件:0 0 0
            no[n+2].in[i] = 1; ///汇点接受的零件是成品:1 1 1
        }
        no[1].perform = INF;
        no[n+2].perform = INF;
    }
    
    int Judge(node no1, node no2) ///判断两条生产线能否交接零件继续加工
    {
        int i;
    
        for (i = 1; i <= m; i++)
            if (no1.out[i] != no2.in[i] && no2.in[i] != 2) ///只有当生产线接受的零件和上一条生产线输出的零件相等或者接受的零件是2时才能接受上一条生产线输出的零件继续加工
                return 0;
    
        return 1;
    }
    
    int BFS(int Start, int End)
    {
        int i, u;
        queue<int>Q;
    
        memset(layer, 0, sizeof(layer));
    
        Q.push(Start);
        layer[Start] = 1;
    
        while (!Q.empty())
        {
            u = Q.front(); Q.pop();
    
            if (u == End) return 1;
    
            for (i = 1; i <= End; i++)
            {
                if (G[u][i] && !layer[i])
                {
                    layer[i] = layer[u]+1;
                    Q.push(i);
                }
            }
        }
    
        return 0;
    }
    
    int DFS(int Start, int End, int mini)
    {
        int i, ans, perform = 0;
    
        if (Start == End) return mini;
    
        for (i = 1; i <= End; i++)
        {
            if (G[Start][i] && layer[i] == layer[Start]+1)
            {
                ans = min(G[Start][i], mini-perform);
                ans = DFS(i, End, ans);
    
                G[Start][i] -= ans;
                G[i][Start] += ans;
                perform += ans;
    
                if (perform == mini) break;
            }
        }
    
        if (perform == 0) layer[Start] = 0;
    
        return perform;
    }
    
    int Dinic(int Start, int End)
    {
        int ans = 0;
    
        while (BFS(Start, End))
            ans += DFS(Start, End, INF);
    
        return ans;
    }
    int main ()
    {
        int i, j, ans, k;
    
        while (scanf("%d%d", &m, &n) != EOF)
        {
            Init();
            k = 0;
    
            for (i = 2; i <= n+1; i++)
            {
                scanf("%d", &no[i].perform);
                for (j = 1; j <= m; j++)
                    scanf("%d", &no[i].in[j]);
                for (j = 1; j <= m; j++)
                    scanf("%d", &no[i].out[j]);
            }
    
            n += 2;
    
            for (i = 1; i <= n; i++)
            {
                for (j = 1; j <= n; j++) ///拆点处理(因为所给权值不是路径上的,而是点上的)
                {
                    if (i == j) g[i][j+n] = G[i][j+n] = no[i].perform; ///说明是同一个点,这时路径变为i~i+n
                    else if (Judge(no[i], no[j])) g[i+n][j] = G[i+n][j] = no[i].perform; ///为了构成回路,使两点之间可以达到,路径变为i+n~j
                } ///拆点后每条路径的权值是输出零件的生产线的权值
            }
    
            ans = Dinic(1, n*2); ///计算生产的零件最多适用于多少台电脑
    
            for (i = 2; i < n; i++)
            {
                for (j = 2; j < n; j++)
                {
                    if (G[i+n][j] < g[i+n][j]) ///说明最大流经过该路径,输出路径及权值
                    {
                        pe[k].x = i; pe[k].y = j; pe[k++].per = g[i+n][j] - G[i+n][j];
                    }
                }
            }
    
            printf("%d %d
    ", ans, k);
            for (i = 0; i < k; i++)
                printf("%d %d %d
    ", pe[i].x-1, pe[i].y-1, pe[i].per);
        }
    
        return 0;
    }
  • 相关阅读:
    Codeforces Round #263 (Div. 2)
    蓝桥杯 翻硬币
    蓝桥杯 错误的票据
    蓝桥杯 带分数
    蓝桥杯 核桃的数量 求三个数的最小公倍数
    poj 3928 ping pong 树状数组
    lca
    poj 3927 Priest John's Busiest Day
    种类并查集
    高桥和低桥 ( 代代相传刷qq + 无敌二分 )
  • 原文地址:https://www.cnblogs.com/syhandll/p/4732402.html
Copyright © 2011-2022 走看看