zoukankan      html  css  js  c++  java
  • 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 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


    这题就两个注意的地方,如果他要求的输入的电脑状态是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
    ",tot);
        for(int i=0;i<tot;i++)
        {
            printf("%d %d %d
    ",path[i][0],path[i][1],path[i][2]);
        }
    }
    int main()
    {
        while(~scanf("%d%d",&p,&n))
        {
            init();
            dinic();
        }
        return 0;
    }
  • 相关阅读:
    linux上安装mysql
    Linux上安装elasticsearch
    解决pyhton aiohttp ssl:None [[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)
    mysql数据库的数据变更事件获取以及相关数据
    [天下小黑盒]打地鼠小助手
    看到当年自己学SQL Server 的笔记
    CodeFirst EF中导航属性的个人理解
    在Win10下如何安装IMSL6.0
    商品中台三期压测
    压测
  • 原文地址:https://www.cnblogs.com/lthb/p/4417139.html
Copyright © 2011-2022 走看看