Poj 3436 ACM Computer Factory【最大流Dinic+建图】

来源:互联网 发布:阿里云ecs重装系统 编辑:程序博客网 时间:2024/06/04 17:51

ACM Computer Factory
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 7353 Accepted: 2617 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.

Source

Northeastern Europe 2005, Far-Eastern Subregion

题目大意:

一共有N个机器,每个机器有P个元素,对应输入的时候输入N个机器的信息,第一个数表示这个机器可以一共能够生产多少产物,接下来2p个元素,前p个元素:其中有三种数值,1,2,0,分别表示必须有这个位子的组件,可有可没有这个位子的组件,以及不能有这个位子的组件。一个中间产物想在这个机器上进行生产接下来的产物,必须要满足这些条件才行,对应在这个机器上产生的产物的各个组件的结果是后p个元素。

输入为0 0 0的机器作为初始机器,输出为1 1 1的机器作为最终生产机器,问最多能够生产多少个产物,对应每个机器之间的相互供给量为多少。


思路:


1、首先能够分析出,这是一道很裸很裸的最大流的题。


2、接下来我们考虑建图:

①建立一个源点S,连入所有输入为0 0 0 的机器,其容量就是这个机器能够生产的产物量。

②建立一个汇点T,将所有输出为1 1 1的机器连入汇点,其容量就是这个机器能够生产的产物量。

③将机器I连入机器J,如果机器i输出的产物能够作为机器J的输入产物的条件下,其容量就是机器i能够生产的产物量。

接下来我们跑一遍最大流Dinic,得到的最大流的值就是整个过程最终能够输出的最大产物量。


3、那么我们考虑处理输出边数问题,其实不难,我们只要考虑退回边和原边的关系即可,退回边的权值就是原边流过的流量值,那么我们遍历所有边,考虑其退回边是否>0,如果是,说明这条边有流流过,那么对应将其记录下来一起输出即可。


Ac代码:


#include<stdio.h>#include<string.h>#include<queue>#include<iostream>using namespace std;struct node2{    int from;    int to;    int w;    int next;}e[1500050];int a[55][255];int cur[15000];int divv[15000];int val[15000];int head[15000];int output[50*50*50*10][3];int n,p,ss,tt,cont;void add(int from,int to,int w){    e[cont].from=from;    e[cont].to=to;    e[cont].w=w;    e[cont].next=head[from];    head[from]=cont++;}void Getmap(){    cont=0;    ss=n+1;    tt=n+2;    memset(head,-1,sizeof(head));    for(int i=1;i<=n;i++)    {        int flag=1;        for(int k=0;k<p;k++)        {            if(a[i][k]==1)flag=0;        }        if(flag==1)        {            add(ss,i,val[i]);            add(i,ss,0);        }        flag=1;        for(int k=p;k<2*p;k++)        {            if(a[i][k]==0)flag=0;        }        if(flag==1)        {            add(i,tt,val[i]);            add(tt,i,0);        }    }    for(int i=1;i<=n;i++)    {        for(int j=1;j<=n;j++)        {            int flag=0;            if(i==j)continue;            for(int k=0;k<p;k++)            {                if(a[i][k+p]+a[j][k]==1)flag=1;            }            if(flag==0)            {                add(i,j,val[i]);                add(j,i,0);            }        }    }}int makedivv(){    queue<int >s;    s.push(ss);    memset(divv,0,sizeof(divv));    divv[ss]=1;    while(!s.empty())    {        int u=s.front();        if(u==tt)return 1;        s.pop();        for(int i=head[u];i!=-1;i=e[i].next)        {            int v=e[i].to;            int w=e[i].w;            if(w&&divv[v]==0)            {                divv[v]=divv[u]+1;                s.push(v);            }        }    }    return 0;}int Dfs(int u,int maxflow,int tt){    int ret=0;    if(u==tt)return maxflow;    for(int &i=cur[u];i!=-1;i=e[i].next)    {        int v=e[i].to;        int w=e[i].w;        if(w&&divv[v]==divv[u]+1)        {            int f=Dfs(v,min(maxflow-ret,w),tt);            e[i].w-=f;            e[i^1].w+=f;            ret+=f;            if(ret==maxflow)return ret;        }    }    return ret;}void Slove(){    int ans=0;    while(makedivv()==1)    {        memcpy(cur,head,sizeof(head));        ans+=Dfs(ss,0x3f3f3f3f,tt);    }    printf("%d",ans);}int main(){    while(~scanf("%d%d",&p,&n))    {        for(int i=1;i<=n;i++)        {            scanf("%d",&val[i]);            for(int j=0;j<p*2;j++)            {                scanf("%d",&a[i][j]);            }        }        Getmap();        Slove();        int cnt=0;        for(int i=0;i<cont;i++)        {            if(i%2==0)            {                if(e[i^1].w>0)                {                    if(e[i].from==ss||e[i].to==tt)continue;                    output[cnt][0]=e[i].from;                    output[cnt][1]=e[i].to;                    output[cnt++][2]=e[i^1].w;                }            }        }        printf(" %d\n",cnt);        for(int i=0;i<cnt;i++)        {            printf("%d %d %d\n",output[i][0],output[i][1],output[i][2]);        }    }}







0 0
原创粉丝点击