zoukankan      html  css  js  c++  java
  • A

    题 意:有一个ACM工厂会生产一些电脑,在这个工厂里面有一些生产线,分别生产不同的零件,不过他们生产的电脑可能是一体机,所以只能一些零件加工后别的生 产线才可以继续加工,比如产品A在生产线1号加工后继续前往生产线2号继续加工,直到成为完全产品。输入 P 意思是这个电脑需要P个零件,N表示有N个生产线,每个生产线都有最大加工量,并且需要什么零件和输出的是什么零件,0表示没有这个零件,1表示有这个零 件,2表示有没有都可以。
    样例说明:
    3 4
    1号: 15  0 0 0 -->  0 1 0
    2号: 10  0 0 0-->  0 1 1
    3号: 30  0 1 2 -->  1 1 1
    4号: 3   0 2 1  -->  1 1 1
    1号生产线需要0 0 0这样的零件(这样的零件也就是无限制零件,源点),它可以把零件加工成 0 1 0 这个样子,然后 3 号生产线可以接受这种零件,并且加工成 1 1 1 也就是成品,到这样也就加工成功了,因为1号生产线每次可以加工 15 个零件,所以1->3的加工量就是 15,同理 2->3的加工量是 10,所以结果是 25。
     
    分析:很明显的网络流题目,感觉难点应该在题目阅读和建图上.....可以用0当做源点 N+1当做汇点,然后每两点都进行匹配一些,看看是否可以连接,路径的权值为出点的生产能力。
     
    注意:因为每个生产线的生产能力有限,所以需要拆点,防止超出他的生产能力,比如下图如果不拆点结果就会使20,实际上是10
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    
    using namespace std;
    
    const int oo=0x3f3f3f3f;
    
    struct node
    {
        int flow;
        int in[55];
        int out[55];
    }a[20];
    
    int maps[111][111];
    int x[10005];int y[10005],z[10005];
    int oldmaps[111][111];
    int layer[111];
    int p,n;
    
    void init()
    {
        memset(maps,0,sizeof(maps));
        memset(oldmaps,0,sizeof(oldmaps));
        for(int i=1;i<=p;i++)
        {
            a[1].in[i]=0;
            a[1].out[i]=0;
            a[n+2].in[i]=1;
            a[n+2].out[i]=1;
        }
        a[1].flow=oo;
        a[n+2].flow=oo;
    }
    
    int can(int x,int y)
    {
        for(int i=1;i<=p;i++)
        {
            if(a[x].out[i]!=a[y].in[i]&&a[y].in[i]!=2)
                return 0;
        }
        return 1;
    }
    
    int bfs(int s,int End)
    {
        memset(layer,0,sizeof(layer));
        queue<int>q;
        q.push(s);
        layer[s]=1;
        while(q.size())
        {
            s=q.front();
            q.pop();
            if(s==End)
            {
                return 1;
            }
            for(int i=1;i<=End;i++)
            {
                if(maps[s][i]&&layer[i]==0)
                {
                    layer[i]=layer[s]+1;
                    q.push(i);
                }
            }
        }
    
        return 0;
    }
    
    int dfs(int s,int End,int maxflow)
    {
        if(s==End)
            return maxflow;
    
        int iflow=0;
        for(int i=1;i<=End;i++)
        {
            if(maps[s][i]>0&&layer[s]==layer[i]-1)
            {
                int flow=min(maxflow-iflow,maps[s][i]);
                flow=dfs(i,End,flow);
                maps[s][i]-=flow;
                maps[i][s]+=flow;
    
                iflow+=flow;
                if(maxflow==iflow)
                    break;
            }
        }
    
        return iflow;
    }
    
    int Dinic()
    {
        int max_flow=0;
        while(bfs(1,n*2))
        {
            max_flow+=dfs(1,n*2,oo);
        }
        return max_flow;
    }
    
    int main()
    {
        while(~scanf("%d%d",&p,&n))
        {
            init();
            for(int i=2; i<=n+1; i++)
            {
                scanf("%d",&a[i].flow);
                for(int j=1; j<=p; j++)
                {
                    scanf("%d",&a[i].in[j]);
                }
                for(int j=1;j<=p;j++)
                {
                    scanf("%d",&a[i].out[j]);
                }
            }
            n+=2;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(i==j)
                    {
                        oldmaps[i][j+n]=maps[i][j+n]=a[i].flow;
                    }
                    else
                    {
                        if(can(i,j))
                            oldmaps[i+n][j]=maps[i+n][j]=min(a[i].flow,a[j].flow);
                        else
                            oldmaps[i+n][j]=maps[i+n][j]=0;
                    }
                }
            }
            int sum=Dinic();
    
            int k=0;
            for(int i=2;i<n;i++)
            {
                for(int j=2;j<n;j++)
                {
                    if(maps[i+n][j]<oldmaps[i+n][j])
                    {
                        x[k]=i;y[k]=j;
                        z[k]=oldmaps[i+n][j]-maps[i+n][j];
                        k++;
                    }
                }
            }
            printf("%d %d
    ",sum,k);
            for(int i=0;i<k;i++)
                printf("%d %d %d
    ",x[i]-1,y[i]-1,z[i]);
        }
    
        return 0;
    }
    /*
    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
    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
    2 2
    100  0 0  1 0
    200  0 1  1 1
    */
  • 相关阅读:
    点击新闻弹出新闻内容,并且新闻内容根据鼠标移动
    阻止用户复制页面上的文字的几种方法
    js简易聊天框- 鼠标和回车键发送消息
    Java——package和import关键字
    Java——static关键字
    Java——单例模式初步
    Java——this关键字
    Java面向对象的特征一:封装性
    Java再谈方法
    Java——对象
  • 原文地址:https://www.cnblogs.com/mengzhong/p/4814145.html
Copyright © 2011-2022 走看看