• 【网络流24题】太空飞行计划


    P1523 - 【网络流24题】太空飞行计划

    Description

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

    Input

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

    Output

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

    Sample Input

    2 3
    10 1 2
    25 2 3
    5 6 7

    Sample Output

    1 2
    1 2 3
    17

    Hint

    Source

    网络流,最大权闭合图,网络最小割

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<vector>
     6 #include<queue>
     7 #include<ctime>
     8 #include<cmath>
     9 #include<map>
    10 #include<set>
    11 #define MAXX 201
    12 #define INF 199999
    13 using namespace std;
    14 struct e{
    15   int nxt,to,w;
    16 }edge[MAXX*MAXX];
    17 int head[MAXX],que[MAXX],vel[MAXX],n,m,tot,ans,y,ans1[MAXX],vis[MAXX];
    18 void add(int u,int v,int ww){edge[++tot].nxt=head[u];head[u]=tot;edge[tot].to=v,edge[tot].w=ww;}
    19 int dinic(int s,int t,int T){
    20   if(s==t)return T;int tag=0;
    21   for(int i=head[s];i;i=edge[i].nxt)if(vel[edge[i].to]==vel[s]+1&&edge[i].w>0){
    22       int d=dinic(edge[i].to,t,min(T-tag,edge[i].w));
    23       edge[i].w-=d;
    24       if(i&1)y=1;else y=-1;
    25       edge[i+y].w+=d;tag+=d;
    26       if(tag==T)return tag;
    27     }return tag;
    28 }
    29 int bfs(int s,int t){
    30   int h=0,ta=0;que[++ta]=s;
    31   for(int i=1;i<=n+m+1;++i)vel[i]=0;vel[s]=1;
    32   while(h!=ta){
    33     int u=que[++h];
    34     for(int i=head[u];i;i=edge[i].nxt)if(!vel[edge[i].to]&&edge[i].w>0){
    35     int to=edge[i].to;
    36     que[++ta]=to;vel[to]=vel[u]+1;
    37     if(to==t)return 1;
    38       }
    39   }return 0;
    40 }
    41 int maxflow(int s,int t){
    42   int flow=0;
    43   while(bfs(s,t))flow+=dinic(s,t,INF);
    44   return flow;
    45 }
    46 void dfs(){
    47   for(int i=1;i<=m;++i)if(vel[i])cout<<i<<" ";cout<<'
    ';
    48   for(int i=m+1;i<=n+m;++i)if(vel[i])cout<<i-m<<" ";
    49 }
    50 int main(){
    51   scanf("%d%d",&m,&n);int s=0,t=n+m+1;
    52   for(int i=1;i<=m;i++){
    53     int x;scanf("%d",&x);ans+=x;
    54     add(s,i,x);add(i,s,0);
    55     char ch=getchar();
    56     while((ch=getchar())!='
    '){
    57       x=ch-'0';
    58       while((ch=getchar())&&ch>='0'&&ch<='9')x=x*10+ch-'0';
    59       add(i,x+m,INF);add(x+m,i,0);if(ch=='
    ')break;
    60     }
    61   }
    62   for(int i=1;i<=n;++i){
    63     int x;scanf("%d",&x);add(i+m,t,x),add(t,i+m,0);
    64   }
    65   int f=maxflow(s,t);ans-=f;dfs();
    66   cout<<"
    ";
    67   cout<<ans;
    68   return 0;
    69 }

    Copyright © 2016 - 2017 Changjun High School of Changsha, Hunan 湘ICP备05007487

  • 相关阅读:
    690. 员工的重要性
    【递推算法】
    【数据排序】快速排序
    【数据排序】车厢重组
    【基本算法--高精度计算】大整数相加
    【基本算法--高精度计算】回文数
    高精度计算 除法 高精除以低精
    PReLU
    重学C++(1)
    概率论基础知识回顾(1)
  • 原文地址:https://www.cnblogs.com/zzmmm/p/6599566.html
Copyright © 2020-2023  润新知