zoukankan      html  css  js  c++  java
  • AC日记——太空飞行计划 洛谷 P2762

    题目背景

    题目描述

    W 教授正在为国家航天中心计划一系列的太空飞行。每次太空飞行可进行一系列商业性实验而获取利润。现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的集合I={I1,I2,…In}。实验Ej需要用到的仪器是I的子集RjÍI。配置仪器Ik的费用为ck美元。实验Ej的赞助商已同意为该实验结果支付pj美元。W教授的任务是找出一个有效算法,确定在一次太空飞行中要进行哪些实验并因此而配置哪些仪器才能使太空飞行的净收益最大。这里净收益是指进行实验所获得的全部收入与配置仪器的全部费用的差额。

    对于给定的实验和仪器配置情况,编程找出净收益最大的试验计划。

    输入输出格式

    输入格式:

    第1行有2 个正整数m和n。m是实验数,n是仪器数。接下来的m 行,每行是一个实验的有关数据。第一个数赞助商同意支付该实验的费用;接着是该实验需要用到的若干仪器的编号。最后一行的n个数是配置每个仪器的费用。

    输出格式:

    第1 行是实验编号;第2行是仪器编号;最后一行是净收益。

    输入输出样例

    输入样例#1:
    2 3
    10 1 2
    25 2 3
    5 6 7
    输出样例#1:
    1 2
    1 2 3
    17

    说明

    感谢@zhouyonglong 提供spj

    思路:

      http://www.cnblogs.com/wuyiqi/archive/2012/03/12/2391960.html

    来,上代码:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    #define maxn 5005
    #define INF 0x7ffffff
    
    using namespace std;
    
    class QueueType {
        private:
            int head,tail,queue[maxn*20];
        public:
            inline void push(int x)
            {
                queue[tail++]=x;
            }
            
            inline void pop()
            {
                head++;
            }
            
            inline int front()
            {
                return queue[head];
            }
            
            inline bool empty()
            {
                if(head>=tail) return true;
                else return false;
            }
            
            inline void clear()
            {
                head=0,tail=0;
            }
    };
    class QueueType que;
    
    struct EdgeType {
        int to,next,flow;
    };
    struct EdgeType edge[maxn*10];
    
    int if_z,ans,cnt=1,deep[maxn],head[maxn];
    int s=0,t=maxn-1,m,n;
    
    char Cget;
    
    inline void in(int &now)
    {
        now=0,if_z=1,Cget=getchar();
        while(Cget>'9'||Cget<'0')
        {
            if(Cget=='-') if_z=-1;
            Cget=getchar();
        }
        while(Cget>='0'&&Cget<='9')
        {
            now=now*10+Cget-'0';
            Cget=getchar();
        }
        now*=if_z;
    }
    
    inline void edge_add(int u,int v,int w)
    {
        edge[++cnt].to=v,edge[cnt].flow=w,edge[cnt].next=head[u],head[u]=cnt;
        edge[++cnt].to=u,edge[cnt].flow=0,edge[cnt].next=head[v],head[v]=cnt;
    }
    
    bool BFS()
    {
        que.clear();
        memset(deep,-1,sizeof(deep));
        que.push(s),deep[s]=0;
        while(!que.empty())
        {
            int pos=que.front();
            for(int i=head[pos];i;i=edge[i].next)
            {
                if(deep[edge[i].to]==-1&&edge[i].flow>0)
                {
                    deep[edge[i].to]=deep[pos]+1;
                    que.push(edge[i].to);
                    if(edge[i].to==t) return true;
                }
            }
            que.pop();
        }
        return false;
    }
    
    int flowing(int now,int flow)
    {
        if(now==t) return flow;
        int oldflow=0;
        for(int i=head[now];i;i=edge[i].next)
        {
            if(deep[edge[i].to]!=deep[now]+1||edge[i].flow<=0) continue;
            int pos=flowing(edge[i].to,min(flow,edge[i].flow));
            flow-=pos;
            oldflow+=pos;
            edge[i].flow-=pos;
            edge[i^1].flow+=pos;
            if(flow==0) return oldflow;
        }
        return oldflow;
    }
    
    void dinic()
    {
        while(BFS()) ans-=flowing(s,INF);
        BFS();
        for(int i=1;i<=m;i++)
        {
            if(deep[i]>=0) printf("%d ",i);
        }
        putchar('
    ');
        for(int i=m+1;i<=n+m;i++)
        {
            if(deep[i]>=0) printf("%d ",i-m);
        }
        putchar('
    ');
        printf("%d
    ",ans);
    }
    
    int main()
    {
        in(m),in(n);int pos;
        char ch[maxn*10];
        for(int i=1;i<=m;i++)
        {
            in(pos);
            ans+=pos;
            edge_add(s,i,pos);
            gets(ch);
            int p=0;
            while(ch[p]!='00')
            {
                if(ch[p]>='0'&&ch[p]<='9')
                {
                    pos=0;
                    while(ch[p]>='0'&&ch[p]<='9')
                    {
                        pos=pos*10+ch[p]-'0';
                        p++;
                    }
                    edge_add(i,pos+m,INF);
                }
                else p++;
            }
        }
        for(int i=1;i<=n;i++)
        {
            in(pos);
            edge_add(m+i,t,pos);
        }
        dinic();
        return 0;
    }
  • 相关阅读:
    万兆铜缆--七类双绞线--光纤等内容
    [51CTO]反客为主 ,Linux 成为微软 Azure 上最流行的操作系统
    [知乎]超线程对游戏来说真的没用吗?
    SQLSERVER2017 最新补丁发布方式
    MSTSC 修改端口的简单方法 3389
    使用WinSW 将 exe 创建成Windows下面 service的方法 (将nginx创建成 services)
    [时政]在美国,是参议院议长的权力大,还是众议院议长的权力大
    内网内使用https 和 使用http 建立连接的速度对比
    Windows下 OpenSSL的安装与简单使用
    [转发]VMware厚置备延迟置零 、 厚置备置零、精简置备 区别
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6435404.html
Copyright © 2011-2022 走看看