POJ3436 ACM Computer Factory

ACM Computer Factory
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 7426   Accepted: 2654   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 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.

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,如果是,说明这条边有流流过,那么对应将其记录下来一起输出即可。

/*
Problem: 3436        User: bbsh
Memory: 888K        Time: 0MS
Language: G++        Result: Accepted
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define FRE(name) freopen(#name".txt","r",stdin);
using namespace std;
const int N=1.5e4+5,M=55;
const int inf=0x3f3f3f3f;
struct edge{int v,cap,next;}e[N*100];int tot=1;
int n,p,S,T,cnt,head[N],dis[N],val[N],res[N*100][3],in[M][N],out[M][N],q[N*50];
int last[N*100];
void add(int x,int y,int z){
    e[++tot].v=y;e[tot].cap=z;e[tot].next=head[x];head[x]=tot;
    e[++tot].v=x;e[tot].cap=0;e[tot].next=head[y];head[y]=tot;
}
bool isNULL(int *in){//与源点相连
    for(int i=1;i<=p;i++) if(in[i]==1) return 0;
    return 1;
}
bool isFULL(int *out){//与源点相连
    for(int i=1;i<=p;i++) if(!out[i]) return 0;
    return 1;
}
bool canLink(int *out,int *in){//普通节点之间的相连
    for(int i=1;i<=p;i++) if(in[i]+out[i]==1) return 0;
    return 1;
}
void mapping(){
    S=0,T=n+1;
    for(int i=1;i<=n;i++){
        if(isNULL(in[i])) add(S,i,val[i]);
        if(isFULL(out[i])) add(i,T,val[i]);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(i==j) continue;
            if(canLink(out[i],in[j])) add(i,j,val[i]);
        }
    }
}
bool bfs(){
    for(int i=S;i<=T;i++) dis[i]=-1;
    int h=0,t=1;dis[S]=0;q[t]=S;
    while(h!=t){
        int x=q[++h];
        for(int i=head[x];i;i=e[i].next){
            if(dis[e[i].v]==-1&&e[i].cap){
                dis[e[i].v]=dis[x]+1;
                if(e[i].v==T) return 1;
                q[++t]=e[i].v;
            }
        }
    }
    return 0;
}
int dfs(int x,int f){
    if(x==T) return f;
    int used=0,t;
    for(int i=head[x];i;i=e[i].next){
        if(e[i].cap&&dis[e[i].v]==dis[x]+1){
            t=dfs(e[i].v,min(e[i].cap,f));
            e[i].cap-=t;e[i^1].cap+=t;
            used+=t;f-=t;
            if(!f) return used;
        }
    }
    if(!used) dis[x]=-1;
    return used;
}
void dinic(){
    int ans=0;
    while(bfs()) ans+=dfs(S,inf);
    printf("%d ",ans);
}
void init(){
    tot=1;cnt=0;
    memset(head,0,sizeof head);
}
int main(){
    //FRE(sh);
    while(scanf("%d%d",&p,&n)==2){
        init();
        for(int i=1;i<=n;i++){
            scanf("%d",&val[i]);
            for(int j=1;j<=p;j++) scanf("%d",&in[i][j]);
            for(int j=1;j<=p;j++) scanf("%d",&out[i][j]);
        }
        mapping();
        for(int i=2;i<=tot;i++) last[i]=e[i].cap;
        dinic();
        for(int i=2;i<=tot;i+=2){
            if(e[i^1].v==S||e[i].v==T) continue;
            if(last[i]!=e[i].cap){
                res[++cnt][0]=e[i^1].v;
                res[cnt][1]=e[i].v;
                res[cnt][2]=last[i]-e[i].cap;
            }
        }
        printf("%d
",cnt);
        for(int i=1;i<=cnt;i++){
            printf("%d %d %d
",res[i][0],res[i][1],res[i][2]);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/shenben/p/6372392.html