ACM Computer Factory(POJ--3436

来源:互联网 发布:多宝视弱视训练软件 编辑:程序博客网 时间:2024/05/17 08:47

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 P N, then N descriptions of the machines. The description of ith machine is represented as by 2 P + 1 integers Qi Si,1 Si,2...Si,P Di,1 Di,2...Di,P, where Qi specifies performance, Si,j — input specification for part jDi,k — output specification for part k.

Constraints

1 ≤ P ≤ 10, 1 ≤ ≤ 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 A B W, where W is the number of computers delivered from A to B per hour.

If several solutions exist, output any of them.

题意:这是一个电脑生产线,每个电脑有p个配件,有n个生产机器,每个生产机器对电脑的配件都有一定的要求,对于i号生产机器,先输入一个Q代表该生产机器的最大生产容量,接下来输入p个数,对应相应配件的输入要求种数,要求有3种:0-该配件不需要存在;1-该配件必须存在;2-该配件可有可无,再输入p个数,对应相应配件的输出要求种数,要求有两种:0-该配件不存在;1-该配件存在。求该生产线最多能生产多少电脑,并且生产机器能两两相连的有几对,是哪几对,每对的生产量是多少。

思路:先建图,给该图添加一个超级源点src和一个超级汇点des,只要生产机器的输入要求都不包含1则该机器为源点,将超级源点与其连一条边;只要生产机器的输出要求每个配件都是1则该机器为汇点,将其与超级汇点连一条边;其余的亮亮枚举,只要机器1的输出要求与机器2的输入要求对应的配件符合要求即可连边,其边的权值即这两个机器容量的最小值。【PS:机器1的某输出配件与机器2的某输入配件的组合为:0 0;0 2;2 0;2 2都可以连边,而如果是0 1;1 0则不可以,则可推出,只要两个加和不等于1则符合要求】。建完图之后就开始根据求最大流的算法求取最大流,在将求完最大流的图与原图相比较,只要是边值减小的就说明该边有生产量,则输出。

Sample Input

Sample input 13 415  0 0 0  0 1 010  0 0 0  0 1 130  0 1 2  1 1 13   0 2 1  1 1 1Sample input 23 55   0 0 0  0 1 0100 0 1 0  1 0 13   0 1 0  1 1 01   1 0 1  1 1 0300 1 1 2  1 1 1Sample input 32 2100  0 0  1 0200  0 1  1 1

Sample Output

Sample output 125 21 3 152 3 10Sample output 24 51 3 33 5 31 2 12 4 14 5 1Sample output 30 0

Hint

Bold texts appearing in the sample sections are informative and do not form part of the actual data.

#include <cstdio>#include <queue>#include <cstring>#include <algorithm>#define Size 100#define INF 0x3f3f3f3fusing namespace std;int mmap1[Size][Size],mmap2[Size][Size],Line[Size][5];int pre[Size],s[Size][Size],d[Size][Size],w[Size],n;queue<int>q;bool bfs(int src,int des){    memset(pre,-1,sizeof(pre));    while(!q.empty())        q.pop();    pre[src]=0;    q.push(src);    while(!q.empty())    {        int xx=q.front();        q.pop();        for(int i=0; i<=n+1; i++)        {            if(pre[i]==-1&&mmap1[xx][i]>0)            {                pre[i]=xx;                if(i==des)                    return true;                q.push(i);            }        }    }    return false;}int MaxFlow(int src,int des){    int maxflow=0;    while(bfs(src,des))    {        int minflow=INF;        for(int i=des; i!=src;i=pre[i])            minflow=min(minflow,mmap1[pre[i]][i]);        for(int i=des; i!=src; i=pre[i])        {            mmap1[pre[i]][i]-=minflow;            mmap1[i][pre[i]]+=minflow;        }        maxflow+=minflow;    }    return maxflow;}int main(){    //freopen("lalala.text","r",stdin);    int m,src,sum,des;    while(~scanf("%d %d",&m,&n))    {        src=0;                      //超级源点        des=n+1;                 //超级汇点        memset(mmap1,0,sizeof(mmap1));     //两个图都要清空        memset(mmap2,0,sizeof(mmap2));        for(int i=1; i<=n; i++)        {            scanf("%d",&w[i]);            sum=1;            for(int j=1; j<=m; j++)            {                scanf("%d",&s[i][j]);                if(s[i][j]==1)                    sum=0;            }            if(sum)            {                mmap1[0][i]=w[i];                mmap2[0][i]=w[i];            }            sum=1;            for(int j=1; j<=m; j++)            {                scanf("%d",&d[i][j]);                if(d[i][j]!=1)                    sum=0;            }            if(sum)            {                mmap1[i][des]=w[i];                mmap2[i][des]=w[i];            }        }        for(int i=1; i<=n; i++)        {            for(int j=1; j<=n; j++)            {                sum=1;                for(int k=1; k<=m; k++)                {                    if((d[i][k]+s[j][k])==1)                    {                        sum=0;                        break;                    }                }                if(sum)                {                    mmap1[i][j]=min(w[i],w[j]);                    mmap2[i][j]=min(w[i],w[j]);                }            }        }        int flow=MaxFlow(src,des);        int line=0;        for(int i=1; i<=n; i++)            for(int j=1; j<=n; j++)            {                if(mmap2[i][j]>mmap1[i][j])                {                    Line[line][0]=i;                    Line[line][1]=j;                    Line[line][2]=mmap2[i][j]-mmap1[i][j];                    line++;                }            }        printf("%d %d\n",flow,line);        for(int i=0; i<line; i++)            printf("%d %d %d\n",Line[i][0],Line[i][1],Line[i][2]);    }    return 0;}<strong></strong>


0 0
原创粉丝点击