poj 3436 网络最大流加打印路径

ACM Computer Factory

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 5689   Accepted: 1954   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

这题就两个注意的地方,如果他要求的输入的电脑状态是0 1 0,那么你就不能把1 1 0放进去,这点我被坑的很惨,然后还有一个就是dinic算法中的反向流其实就是路径,这点很容易想明白的。下附ac代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<climits>
using namespace std;
struct Comp
{
    int need[11];
    int give[11];
    int num;
}comp[60];
int s[60];
int t[60];
int pre[60];
int sum;
int p,n;
int sign[4000];
int flow[4000];
int path[4000][3];
struct Edge
{
    int s,t,c,next;
}edge[8000];
int head[4000];
int comps,compt,tot;
int minn(int a,int b)
{
    return a<b?a:b;
}
void init()
{
    memset(comp,0,sizeof(comp));
    comps=compt=0;
    for(int i=1;i<=n;i++)
    {
        int ok=0;
        scanf("%d",&comp[i].num);
        for(int j=0;j<p;j++)
        {
            scanf("%d",&comp[i].need[j]);
            if(comp[i].need[j]!=1)
                ok++;
        }
        if(ok==p)
            s[comps++]=i;
        ok=0;
        for(int j=0;j<p;j++)
        {
            scanf("%d",&comp[i].give[j]);
            if(comp[i].give[j]==1)
                ok++;
        }
        if(ok==p)
            t[compt++]=i;
    }
    int ent=0;
    memset(head,-1,sizeof(head));
    for(int i=1;i<=n;i++)
    {
        int ok1=1;
        for(int k=0;k<p;k++)
        {
            if(comp[i].give[k]==0)
            {
                ok1=0;break;
            }
        }
        if(ok1)continue;
        for(int j=1;j<=n;j++)
        {
            int ok2=1;
            for(int k=0;k<p;k++)
            {
                if(comp[j].need[k]==1)
                {
                    ok2=0;break;
                }
            }
            if(ok2)continue;
            int ok=1;
            for(int k=0;k<p;k++)
            {
                if(comp[i].give[k]==0)
                {
                    if(comp[j].need[k]==1)
                    {
                        ok=0;
                        break;
                    }
                }
                if(comp[i].give[k]==1)
                {
                    if(comp[j].need[k]==0)
                    {
                        ok=0;break;
                    }
                }
            }
            if(ok)
            {
                edge[ent].s=i;edge[ent].t=j;edge[ent].c=minn(comp[i].num,comp[j].num);flow[ent]=edge[ent].c;edge[ent].next=head[i];head[i]=ent++;
                edge[ent].s=j;edge[ent].t=i;edge[ent].c=0;flow[ent]=0;edge[ent].next=head[j];head[j]=ent++;
            }
        }
    }
    for(int i=0;i<comps;i++)
    {
        edge[ent].s=0;edge[ent].t=s[i];edge[ent].c=comp[s[i]].num;flow[ent]=edge[ent].c;edge[ent].next=head[0];head[0]=ent++;
        edge[ent].s=s[i];edge[ent].t=0;edge[ent].c=0;flow[ent]=0;edge[ent].next=head[s[i]];head[s[i]]=ent++;
    }
    for(int j=0;j<compt;j++)
    {
        edge[ent].s=t[j];edge[ent].t=n+1;edge[ent].c=comp[t[j]].num;flow[ent]=edge[ent].c;edge[ent].next=head[t[j]];head[t[j]]=ent++;
        edge[ent].s=n+1;edge[ent].t=t[j];edge[ent].c=0;flow[ent]=0;edge[ent].next=head[n+1];head[n+1]=ent++;
    }
}
bool bfs(int start,int end)
{
    memset(pre,-1,sizeof(pre));
    pre[start]=0;
    queue<int>q;
    q.push(start);
    while(!q.empty())
    {
        int temp=q.front();
        q.pop();
        for(int i=head[temp];i!=-1;i=edge[i].next)
        {
            int temp2=edge[i].t;
            if(pre[temp2]==-1&&edge[i].c)
            {
                pre[temp2]=pre[temp]+1;
                q.push(temp2);
            }
        }
    }
    return pre[end]!=-1;
}
int dfs(int start,int end,int Min)
{
    if(start==end) return Min;
    int flow=0;
    for(int i=head[start];i!=-1;i=edge[i].next)
    {
        int temp=edge[i].t;
        if(pre[temp]==pre[start]+1&&edge[i].c)
        {
            int small=minn(Min-flow,edge[i].c);
            small=dfs(temp,end,small);
            if(small!=0)
            flow+=small;
            edge[i].c-=small;
            edge[i^1].c+=small;
        }
    }
    return flow;
}
void dinic()
{
    tot=0;sum=0;
    int flows=0,i=0;
    while(bfs(0,n+1))
        flows+=dfs(0,n+1,INT_MAX);
    printf("%d ",flows);
    for(int i=1;i<=n;i++)
    {
        for(int j=head[i];j!=-1;j=edge[j].next)
        {
            if(edge[j].t==0||edge[j].t==n+1)continue;
            if(edge[j].c!=0&&flow[j]==0)
            {
                path[tot][0]=edge[j].t;path[tot][1]=i;path[tot][2]=edge[j].c;
                tot++;
            }
        }
    }
    printf("%d\n",tot);
    for(int i=0;i<tot;i++)
    {
        printf("%d %d %d\n",path[i][0],path[i][1],path[i][2]);
    }
}
int main()
{
    while(~scanf("%d%d",&p,&n))
    {
        init();
        dinic();
    }
    return 0;
}
时间: 2024-12-28 21:00:56

poj 3436 网络最大流加打印路径的相关文章

uva1626 poj 1141 Brackets Sequence 区间dp 打印路径

// poj 1141 Brackets Sequence // 也是在紫书上看的一题,uva就是多了一个t组数据. // 经典区间dp // dp(i,j)表示区间[i,j]内所需要增加的括号数目 // 则分为两种情况 // 一种是s[i]和s[j]是匹配的则 // dp[i][j] = min(dp[i][j],dp[i+1][j-1]) // 另外一种情况是不匹配 // dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]){i<k<j}; // 但是无

A - ACM Computer Factory - poj 3436(最大流)

题意:有一个ACM工厂会生产一些电脑,在这个工厂里面有一些生产线,分别生产不同的零件,不过他们生产的电脑可能是一体机,所以只能一些零件加工后别的生产线才可以继续加工,比如产品A在生产线1号加工后继续前往生产线2号继续加工,直到成为完全产品.输入 P 意思是这个电脑需要P个零件,N表示有N个生产线,每个生产线都有最大加工量,并且需要什么零件和输出的是什么零件,0表示没有这个零件,1表示有这个零件,2表示有没有都可以. 样例说明: 3 4 1号: 15 0 0 0 --> 0 1 0 2号: 10

poj1087 网络最大流

http://poj.org/problem?id=1087 Description You are in charge of setting up the press room for the inaugural meeting of the United Nations Internet eXecutive (UNIX), which has an international mandate to make the free flow of information and ideas on

POJ 3436 ACM Computer Factory(网络最大流)

http://poj.org/problem?id=3436 ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5286   Accepted: 1813   Special Judge Description As you know, all the computers used for ACM contests must be identical, so the particip

POJ 3436 ACM Computer Factory (最大流 + 输出路径)

POJ 3436 ACM Computer Factory 链接:http://poj.org/problem?id=3436 题意:每台电脑有P部分,可以通过不同的机器来进行加工.有N台机器,每台机器用2 P +1 个整数来描述:Qi  Si,1  Si,2 ...  Si,p  Di,1  Di,2. ..  Di,p,其中Qi 指定了机器的性能,表示每小时加工的电脑数量.Si,j 为第j 部分的输入规格,0表示该部分不能被加工过,1表示该部分必须被加工过,2表示都可以.Di,k 为第k 部

POJ 1273 Drainage Ditches (网络最大流)

http://poj.org/problem?id=1273 Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 55235   Accepted: 21104 Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This means

POJ 1637 Sightseeing tour (混合图欧拉回路,网络最大流)

http://poj.org/problem?id=1637 Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7498   Accepted: 3123 Description The city executive board in Lund wants to construct a sightseeing tour by bus in Lund, so that tourists can

POJ 3281 Dining(网络最大流)

http://poj.org/problem?id=3281 Dining Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9121   Accepted: 4199 Description Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, and she will consume no others.

Poj 3436 ACM Computer Factory (最大流)

题目链接: Poj 3436 ACM Computer Factory 题目描述: n个工厂,每个工厂能把电脑s态转化为d态,每个电脑有p个部件,问整个工厂系统在每个小时内最多能加工多少台电脑? 解题思路: 因为需要输出流水线要经过的工厂路径,如果要用电脑状态当做节点的话,就GG了.所以建图的时候要把工厂当做节点.对于节点i,能生产si电脑的节点可以进入节点i,能转化ei电脑的节点可以由i节点进入.要注意对于每一个节点要进行拆点,防止流量发生错误. 1 #include <queue> 2 #