poj3436 ACM Computer Factory

来源:互联网 发布:阴茎粗大的感受 知乎 编辑:程序博客网 时间:2024/06/05 00:45

ACM Computer Factory
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 7143 Accepted: 2533 Special Judge

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.

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.

题意:我是直接在这懵逼了一下午QAQ ,依旧是不明白说了个什么事啊,我只好去寻求帮助惹qwq。

大意就是我要建立一条电脑生产线。输入p表示完成一台电脑要p部分零件。n表示我现在有n台可以用来生产的机器。之后n行,

显示p个数表示这台机器需要哪几个部分的零件。0表示我必须没有这个零件,1表示我必须要这个零件,2表示有没有这个零件都可以。

再来p个数表示这台机器可以生产出哪几部分零件。0表示生产不出,1表示可以生产出。

然后现在让你求最多可以生产出多少台电脑,如果可以生产出,则输出通过的路径两台机器间的流量。

思路:

仔细想一想就是多起点多终点的最大流问题,所以我们需要虚拟一个起点s和汇点t。

1.图上的起点自然是,不需要任何机器零件就可以加工的机器,把这台机器和虚拟起点连接起来,权值就是这台机器的流量。

2.而终点自然就是,能够最后加工出一台机器全部零件的机器,把这台机器和虚拟终点连接起来,权值自然也是这台机器的流量。

3.然后就是看一看这个点还可以和哪些点相连。假设i点可以和j点相连的话,那么说明i机器的输出部分零件分别和j机器的输入零件全部相匹配。

j输入是2直接匹配,输入是1那么i输出必须是1,输入是0那么输出必须是0。

4.关于得出流量的问题。我们在进行EK算法之前,先把图复制一份,待跑完EK算法后,把复制的图和最终的残余图作比较,差的部分自然是走过的流量了~


#include <iostream>#include <cstdio>#include <algorithm>#include <queue>#include <cstring>using namespace std;const int inf = 0x7ffffff;const int MAXN = 50+5;int n,p,s,e,tu[MAXN][MAXN],temp[MAXN][MAXN],path[MAXN],flow[MAXN];struct node{    int num;    int in[12];    int out[12];}machine[MAXN];int bfs(){    int i,k;    memset(path,-1,sizeof(path));    flow[s]=inf;    path[s]=0;    queue<int>q;    q.push(s);    while(!q.empty())    {        k=q.front();        q.pop();        if(k==e)break;        for(i=1;i<=e;++i)        {            if(path[i]==-1&&tu[k][i])            {                flow[i]=min(flow[k],tu[k][i]);                q.push(i);                path[i]=k;            }        }    }    if(path[e]==-1)return -1;    return flow[e];}int EK(){    int max_flow=0,step,pre,now;    while((step=bfs())!=-1)    {        max_flow+=step;        now=e;        while(now!=s)        {            pre=path[now];            tu[pre][now]-=step;            tu[now][pre]+=step;            now=pre;        }    }    return max_flow;}int main(){    int i,j,k;    while(~scanf("%d%d",&p,&n))    {        for(i=1;i<=n;++i)        {            scanf("%d",&machine[i].num);            for(j=0;j<p;++j)scanf("%d",&machine[i].in[j]);            for(j=0;j<p;++j)scanf("%d",&machine[i].out[j]);        }        memset(tu,0,sizeof(tu));        for(i=1;i<=n;++i)        {            //查看是不是能够和虚拟起点相连            for(j=0;j<p;++j)if(machine[i].in[j]==1)break;            if(j==p)tu[0][i]=machine[i].num;            //查看是不是能够和虚拟终点相连            for(j=0;j<p;++j)if(!machine[i].out[j])break;            if(j==p)tu[i][n+1]=machine[i].num;            //查看还能不能够和其他的点相连            for(j=1;j<=n;++j)            {                if(i==j)continue;                for(k=0;k<p;++k)if(machine[i].out[k]+machine[j].in[k]==1)break;                if(k==p)tu[i][j]=min(machine[i].num,machine[j].num);            }        }        s=0;e=n+1;        memcpy(temp,tu,sizeof(tu));//复制,为了以后作比较        int max_flow=EK();        int ans[MAXN][3];        int cnt=0;        for(i=1;i<=n;++i)            for(j=1;j<=n;++j)            {                if(temp[i][j]>tu[i][j])                {                    ans[cnt][0]=i;                    ans[cnt][1]=j;                    ans[cnt++][2]=temp[i][j]-tu[i][j];                }            }            printf("%d %d\n",max_flow,cnt);            for(i=0;i<cnt;++i)printf("%d %d %d\n",ans[i][0],ans[i][1],ans[i][2]);    }    return 0;}





1 0
原创粉丝点击