zoukankan      html  css  js  c++  java
  • 开发计划

    开发计划

    baidu,google我都试过了,全网都没有这题的题解,只有一份pascal的标程,于是决定造福人类

    Description

    Juicepry®公司准备制定一份未来一段时期内的科研与产品开发计划。公司的各部门,都提出各自的计划项目,汇总成一张计划表。该计划表包含了许多项目,每个项目是一个研究课题,一个技术试验,一项市场调查,或者是一个推销活动,等等。对于每个项目,计划表中都给出了它的预算,开支或者盈利。由于某些项目的进行必须依赖其他项目的成果,所以如果要进行这个项目的话,它所依赖的项目也是必不可少的。例如,要推出一个新产品,先要分析其消费群体的需求,对产品的性能做出定位,然后设计产品的各个细节,包括形象包装,等等。现在假设你是Juicipry®公司的总裁,你的目标是从这份计划项目表中挑选出一些项目,使得你的公司能获得最大的利润。

    Input

    包括项目的数量N,以及每个项目的预算Ci和他所依赖的项目集合Pi。格式如下:
    第1行是N;
    第2~n+1行每行表示一个项目的信息。
    每行第一个数是Ci,正数表示盈利,负数表示开支。剩下的数表示项目i所依赖的项目。每行相邻的两个数之间用一个或多个空格隔开。
    0≤N≤3000
    -1000000≤Ci≤1000000

    Output

    第1行是公司的最大利润。接着是获得最大利润的方案。若有多个方案,则输出所选项目最少的。每行一个数,表示选择的项目,所有项目按从小到大排序。

    Solution

    网络流建图:

    对于每个项目,将其视为一个点,源点为s=0,汇点为t=n+1

    若p项目盈利(ci>0),则将s与p连边,容量为ci

    若p项目亏损(ci<0),则将p与t连边,容量为-ci

    若p项目依赖q,则将p与q连边,容量为inf

    建完图跑一遍dinic就好了(^o^)/

    则 纯获利=盈利项目之和-最小割

    那么选择的项目就是S集中的点啦,dfs求出来就好了

    Code

    #include<bits/stdc++.h>
    #define inf 0x7fffffff
    #define N 3005
    using namespace std;
    int n,st,ed,tot,s,t,lw[N],head[N],cnt=1,dis[N];
    struct Line{int to,nxt,val;}l[N*N];
    void ins(int x,int y,int z){
        l[++cnt].to=y,l[cnt].nxt=head[x],l[cnt].val=z,head[x]=cnt;
        l[++cnt].to=x,l[cnt].nxt=head[y],l[cnt].val=0,head[y]=cnt;
    }
    bool bfs(){
        memset(dis,0,sizeof(dis));
        queue<int>q;
        dis[st]=1,q.push(st);
        while(q.size()){
            int x=q.front();q.pop();
            for(int i=head[x],y;i;i=l[i].nxt){
                y=l[i].to;
                if(l[i].val&&!dis[y]){
                    dis[y]=dis[x]+1;
                    if(y==ed)return true;
                    q.push(y);
                }
            }
        }
        return false;
    }
    int dfs(int x,int limit){
        if(x==ed)return limit;
        int tmp=limit;
        for(int i=head[x],k,y;i;i=l[i].nxt){
            y=l[i].to;
            if(dis[y]!=dis[x]+1||!l[i].val)continue;
            if((k=dfs(y,min(tmp,l[i].val)))){
                l[i^1].val+=k,l[i].val-=k;
                tmp-=k;
            }else dis[y]=0;
            if(!tmp)return limit;
        }
        return limit-tmp;
    }
    int dinic(int S,int T){
        st=S,ed=T;int re=0;
        while(bfs())re+=dfs(st,inf);
        return re;
    }
    int ans[N],top;
    bool vis[N];
    void pushin(int x){
        if(!vis[x])vis[x]=true,ans[top++]=x;
        else return;
        for(int i=head[x];i;i=l[i].nxt){
            if(!l[i].val)continue;
            pushin(l[i].to);
        }
    }
    signed main(){
        scanf("%d",&n),s=0,t=n+1;
        for(int i=1,ci,ai;i<=n;i++){
            scanf("%d",&ci);
            if(ci>0)tot+=ci,ins(s,i,ci);
            if(ci<0)ins(i,t,-ci);
            char ch;
            while(~scanf("%c",&ch)){
                if(ch!=' ')break;
                scanf("%d",&ai);
                ins(i,ai,inf);
            }
        }
        printf("%d
    ",tot-dinic(s,t));//盈利项目之和-最小割(最小割=最大流)
        pushin(0);//dfs求S集
        sort(ans,ans+top);
        for(int i=1;i<top;i++)printf("%d
    ",ans[i]);
        return 0;
    }

    读入十分恶心,交了37次才A过QAQ

  • 相关阅读:
    Junit单元测试
    团队作业1——团队展示&教辅宝
    结对编程加强版四则运算器
    APP分析之海豚睡眠
    作业1--四则运算
    软件工程-pair work[附加题]
    现代程序设计 homework-02
    《软件工程》individual project开发小记(一)
    现代程序设计 homework-01
    《现代程序设计》9.9日课后总结
  • 原文地址:https://www.cnblogs.com/nlKOG/p/10318480.html
Copyright © 2011-2022 走看看