poj 3436 网络流构图经典

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

Source

Northeastern Europe 2005, Far-Eastern Subregion
 
 
 

大概题意,每个机器有P个组件组成,现在给你M个机器的信息,问你最多能组装多少个电脑。

没行第一个参数 能容纳多少台电脑(可以看成网络流中,没条路的容量)

接下来有2P个参数 0 表示不需要 1表示必须有 2可以可有可无第2~p个参数 分别是安装这个电脑前需要的的条件

第p+1个参数到2P个参数表示 安装好后的机器具备那些组件例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

第一台机器可以装容纳15台机器,生产条件是全0(红色部分) 生产结果是(绿色部分) 这里只有第3第4台机器可以把整台电脑安装好,而进入机器3需要条件 0 1 2也就是第二个部件必须有,显然刚由1生产过的电脑能送到机器3组装成完整的电脑

这里我们可以采用拆点的方法去建立一个图来进行最短增广路得出结果当然需要有一个超级汇点和超级源点,显然把生产条件都是0的与超级源点相连,生产结果全为1的与超级汇点相连 权值当然是无穷大。然后把每台机器的生产条件和生产结果连接起来,因为在同一台机器。当然是连通的拉!权值当然是自己所能容纳的量机器之间怎么连接?00 11 21 12都可以匹配,而01 10就不能匹配,所以我们就可以轻易得出结论同部件相加等于1的机器不能相连;相连的机器权值为无穷大,这样我们的图就建好了!然后就可以用spfa,EK,dinic等算法解决,我这里用的是ISAP。

 

 

 

 

 

 

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
int p,n;
int a[100][50];
int edge[100][100];
int flow[100][100];
int start,end;
int head[100];
int pp[100];
int EK(){
     memset(flow,0,sizeof(flow));
     memset(head,-1,sizeof(head));

     int sum=0;
     while(true){
        queue<int>q;
        q.push(start);
        memset(pp,0,sizeof(pp));

       pp[start]=0x7fffffff;

        while(!q.empty()){
            int u=q.front();
            q.pop();
            for(int v=0;v<=n+1;v++){
                if(!pp[v]&&edge[u][v]>flow[u][v]){
                    head[v]=u;
                    q.push(v);
                    pp[v]=min(pp[u],edge[u][v]-flow[u][v]);

                }
            }

        }

        if(pp[end]==0)
            break;
        for(int i=end;i!=start;i=head[i]){
            flow[head[i]][i]+=pp[end];
            flow[i][head[i]]-=pp[end];
        }
        sum+=pp[end];
     }
     return sum;

}
int main(){
     while(scanf("%d%d",&p,&n)!=EOF){
        memset(a,0,sizeof(a));
        memset(edge,0,sizeof(edge));
        start=0;
        end=n+1;
        for(int i=0;i<=2*p+1;i++){
            a[0][i]=0;
            a[n+1][i]=1;
        }
        for(int i=1;i<=n;i++){
            for(int j=0;j<=2*p;j++){
                scanf("%d",&a[i][j]);
            }
        }


        for(int i=0;i<=n+1;i++){
            for(int j=0;j<=n+1;j++){
                    if(i==j)
                      continue;
                bool flag=true;
            for(int k=1;k<=p;k++){
                if(!(a[j][k]==2||a[i][k+p]==a[j][k]))
                    flag=false;

                }

                if(flag&&i==0){
                    edge[0][j]=a[j][0];
                }
                else if(flag&&j==n+1){
                    edge[i][n+1]=a[i][0];
                }
                else if(flag){
                    edge[i][j]=min(a[i][0],a[j][0]);
                }

            }
        }

        int total=EK();
        printf("%d ",total);
        int cnt=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(flow[i][j]>0)
                    cnt++;
            }
        }
        printf("%d\n",cnt);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(flow[i][j]>0){
                    printf("%d %d %d\n",i,j,flow[i][j]);
                }
            }
        }


     }
     return 0;
}

 

 
 
 
 
 
 
posted @ 2015-08-02 21:55  柳下_MBX  阅读(219)  评论(0编辑  收藏  举报