poj 3436 ACM Computer Factory

ACM Computer Factory
Time Limit: 1000MS   Memory Limit: 65536K
        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 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 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 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

Hint

Bold texts appearing in the sample sections are informative and do not form part of the actual data.
题目大意:
有p个零部件,n台机器
接下来n行,每行
第一个数字表示这台机器最多能组装几个零部件,
后面p个数,表示要由这台机器组装,零部件要满足的条件 ,可能为0,1,2,分别表示这个零部件必须还没有组装,必须已经组装,组装不组装都行
后面再p个数 ,表示由这台机器组装完毕后,零部件的情况,可能为0,1,分别表示 这个零部件没有组装,已经组装
拆点+最大流
构图方法:
1、若机器组装零部件要满足的情况中没有1,源点向这个机器连一条inf边
2、每台机器拆为2个点,i和n+i,流量为机器最多组装零件数
3、若机器i组装零件完毕后,零件的情况 与机器j组装之前零件的情况相等  或 不相等的零件在机器j中条件为2,由i+n向j连一条inf边
4、若机器i组装零件后全是1,由i+n向汇点连一条inf边
路径输出方法:
枚举所有与n+i相连的边,如果这条边指向的点不是汇点,不是i,流量不是inf,就记录i,to[i],inf-cap[i]
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<iostream>
#define inf 600001
using namespace std;
int n,p,tot=1,ans;
int src,decc,Q[51];
int front[111],cap[8001],lev[111],cnt[111],next[8001],to[8001];
string in[51],out[51],begin,end;
queue<int>q;
int output[201][4],sum;
bool check1(int k)
{
    if(in[k]==begin) return true;
    for(int i=0;i<p;i++)
     if(in[k][i]=='1') return false;
    return true;
}
bool check2(int k)
{
    if(out[k]==end) return true;
    return false;
}
bool check3(int k,int l)
{
    if(out[k]==in[l]) return true;
    for(int i=0;i<p;i++)
     if(out[k][i]!=in[l][i]&&in[l][i]!='2') return false;
    return true;
      
}
void add(int u,int v,int w)
{
    to[++tot]=v;cap[tot]=w;next[tot]=front[u];front[u]=tot;
    to[++tot]=u;cap[tot]=0;next[tot]=front[v];front[v]=tot;
}
bool bfs()
{
    for(int i=0;i<=2*n+1;i++) {cnt[i]=front[i];lev[i]=-1;}
    while(!q.empty()) q.pop();
    q.push(src);lev[src]=0;
    while(!q.empty())
    {
        int now=q.front();q.pop();
        for(int i=front[now];i!=0;i=next[i])
        {
            int t=to[i];
            if(cap[i]>0&&lev[t]==-1)
            {
                q.push(t);
                lev[t]=lev[now]+1;
                if(t==decc) return true;
            }
        }
    }
    return false;
}
int dinic(int now,int flow)
{
    if(now==decc) return flow;
    int delta,rest=0;
    for(int & i=cnt[now];i!=0;i=next[i])
    {
        int t=to[i];
        if(lev[t]==lev[now]+1&&cap[i]>0)
        {
            delta=dinic(t,min(cap[i],flow-rest));
            if(delta)
            {
                cap[i]-=delta;cap[i^1]+=delta;
                rest+=delta;if(rest==flow) break;
            }
        }
    }
    if(rest!=flow) lev[now]=-1;
    return rest;
}
int main()
{
    while(    scanf("%d%d",&p,&n)!=EOF)
  {
     memset(front,0,sizeof(front));sum=0;ans=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&Q[i]);
        in[i]=out[i]="";
        char c;
        for(int j=1;j<=p;j++) 
        {
            cin>>c;in[i]+=c;
        }
        for(int j=1;j<=p;j++)
        {
            cin>>c;out[i]+=c;
        }
    }
    begin=end="";
    for(int i=1;i<=p;i++)  begin+='0',end+='1';
    decc=2*n+1;
    for(int i=1;i<=n;i++) add(i,n+i,Q[i]);
    for(int i=1;i<=n;i++)
    {
        if(check1(i)) 
         add(src,i,inf);
        if(check2(i)) 
         add(i+n,decc,inf);
        for(int j=1;j<=n;j++)
         if(check3(i,j)) 
          add(i+n,j,inf);
    }
    while(bfs()) 
     ans+=dinic(src,inf);
    printf("%d ",ans);
    for(int i=1;i<=n;i++)
    {
        for(int j=front[n+i];j;j=next[j])
        {
            if(to[j]==decc||cap[j]==inf||to[j]==i) continue;
            sum++;
            output[sum][1]=i;
            output[sum][2]=to[j];
            output[sum][3]=inf-cap[j];
        }
    }
    printf("%d\n",sum);
    for(int i=1;i<=sum;i++)
     printf("%d %d %d\n",output[i][1],output[i][2],output[i][3]);
  }
}

 

posted @ 2017-03-03 15:21  TRTTG  阅读(308)  评论(0编辑  收藏  举报