洛谷 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//spj好评

解题思路

  最大权闭合子图的入门题,这个模型我是看这篇博文看懂的。图要这样建——

  从S向所有实验连边,边容量为该实验收入,从每个实验向每个需要的设备连边,边权为inf,从每个设备向T连边,边权为该设备费用。

  答案为所有实验的总收入(不用减去成本)的总和减去上图从S到T的最大流。

源代码

#include<queue>
#include<cstdio>
#include<cstring>
int n,m;
int s,t;
struct Edge{
    int next,to,f;
}e[100010]={0};
int cnt=2,head[100010]={0};
void add(int u,int v,int f)
{
    e[cnt]={head[u],v,f};
    head[u]=cnt++;
    e[cnt]={head[v],u,0};
    head[v]=cnt++;
}

int dis[100010]={0};
bool vis[100010]={0};
bool bfs()
{
    memset(dis,0,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[s]=1;
    std::queue<int> q;
    q.push(s);
    vis[s]=1;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int i=head[u];i;i=e[i].next)
        {
            int v=e[i].to;
            if(!dis[v]&&e[i].f>0)
            {
                dis[v]=dis[u]+1;
                q.push(v);
                vis[v]=1;
            }
        }
    }
    return dis[t]!=0;
}

int dfs(int u,int flow)
{
    if(u==t||flow==0) return flow;
    int flow_sum=0;
    for(int i=head[u];i;i=e[i].next)
    {
        int v=e[i].to,f=e[i].f;
        if(dis[v]!=dis[u]+1||f==0) continue;
        int temp=dfs(v,std::min(flow-flow_sum,f));
        e[i].f-=temp;
        e[i^1].f+=temp;
        flow_sum+=temp;
        if(flow_sum>=flow) break;
    }
    if(!flow_sum) dis[u]=-1;
    return flow_sum;
}

int dinic()
{
    int ans=0;
    while(bfs())
    {
        while(int temp=dfs(s,0x7fffffff))
            ans+=temp;
    }
    return ans;
}

int main()
{
    //freopen("shuttle.in","r",stdin);
    //freopen("shuttle.out","w",stdout);
    scanf("%d%d",&m,&n);
    s=n+m+1,t=s+1;
    int ans=0;
    for(int i=1,w;i<=m;i++)
    {
        scanf("%d",&w);
        ans+=w;
        add(s,i,w);
        char ch=getchar();
        while(ch==‘ ‘)
        {
            scanf("%d%c",&w,&ch);
            add(i,w+m,0x7fffffff);
        }
    }
    for(int i=1,w;i<=n;i++)
    {
        scanf("%d",&w);
        add(m+i,t,w);
    }
    int temp=ans-dinic();

    /*for(int i=1;i<=m;i++)
        if(vis[i]) printf("%d ",i);
    printf("\n");
    for(int i=1;i<=n;i++)
        if(vis[i+m]) printf("%d ",i);*/
    for(int i=head[s];i;i=e[i].next)
        if(e[i].f==0) printf("%d ",e[i].to);
    printf("\n");
    for(int i=head[t];i;i=e[i].next)
        if(e[i^1].f==0) printf("%d ",e[i^1].to-m);

    putchar(‘\n‘);
    printf("%d\n",temp);
    return 0;
}
时间: 2024-12-23 15:52:53

洛谷 P2762 太空飞行计划问题的相关文章

luogu P2762 太空飞行计划问题

好像是最大权闭合图,也就是最大流最小割啦,找出最大流的路径输出,这题如何建模呢,一样的先设源点和汇点,源点向每个计划连capacity为赞助数的边,每个计划连相应装置capacity为无穷的边,每个装置向汇点连capacity为支付费用的边,这样,最大利润就是赞助总数-最大流啦,如何证?看两个例子 若是可行方案,相减即为利润,若是不可行方案,相减就为0,数学归纳法可推知n个时也对 另一个问题,如何找到最大权闭合图呢,最后一次分层的level数组就可以帮忙了,我们知道退出dinic算法就是无法到达

网络流24题 P2762 太空飞行计划问题

题目链接 思路 问题模型:最大权闭合图 转化模型:网络最小割 这道题是网络流中一个比较重要的模型:最大权闭合图转最大流 建立超级源点\(S\)和超级汇点\(T\),然后每个实验连一条从\(S\)到实验,流量为实验收益的边,每个仪器连一条从仪器到\(T\), 流量为仪器耗费的边,然后需要的仪器就连一条从实验到仪器流量为\(inf\)(无穷大)的边,因为实验到仪器的边的流量为正无穷,所以最小割一定不会在上面,根据最大流最小割定理,最大流就等于最小割,我们按照以上所说建图,求出最大流,之后用实验利益的

[FZYZOJ 1355] 8-2 太空飞行计划问题

P1355 -- 8-2 太空飞行计划问题 时间限制:1000MS 内存限制:131072KB Description W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的集合I={I1,I2,…In}.实验Ej需要用到的仪器是I的子集RjÍI.配置仪器Ik的费用为ck美元.实验Ej的赞助商已同意为该实验结果支付pj美元.W教授的任务是找出一个有效算法,确定在

题解:线性规划与网络流24题 T2 太空飞行计划问题

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

LibreOJ #6001. 「网络流 24 题」太空飞行计划 最大权闭合图

#6001. 「网络流 24 题」太空飞行计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合 E={E1,E2,?,Em} E = \{ E_1, E_2, \cdots, E_m \}E={E?1??,E?2??,?,E?m??},和进行这些实验

线性规划与网络流24题第2题 太空飞行计划 最小割

/** 题目: 线性规划与网络流24题第2题 太空飞行计划 最小割 链接:http://www.cogs.pro/cogs/problem/problem.php?pid=727 题意:lv 思路:最大点权独立集(点集中任意两个点没有边相连,且点权和最大)=点权总和-最小点权覆盖集. 将实验和仪器看做节点. 实验放在二分图的左边, s->x, cap = 实验利润. 仪器放在右边, x->t, cap = 仪器费用. 如果实验u的进行需要仪器v,u->v, cap = INF. ans

NYIST 531 太空飞行计划

太空飞行计划 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述        W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的集合I={I1,I2,…In}.实验Ej需要用到的仪器是I的子集Rj .配置仪器Ik的费用为ck美元.实验Ej的赞助商已同意为该实验结果支付pj美元.W教授的任务是找出一个有效算法,确定在一次太空飞行中要

洛谷P1132 数字生成计划 广搜

洛谷P1132 数字生成计划 广搜 三种操作 因为要步数最少,所以广搜 1 #include <bits/stdc++.h> 2 #define For(i,j,k) for(int i=j;i<=k;i++) 3 using namespace std ; 4 5 const int N = 1000011 ; 6 struct node{ 7 int a,ans ; 8 }; 9 bool flag[N] ; 10 int f[N] ; 11 queue<node> q;

[网络流24题] 太空飞行计划 (最大权闭合子图---网络最大流)

727. [网络流24题] 太空飞行计划 ★★☆ 输入文件:shuttle.in 输出文件:shuttle.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的集合I={ I1, I2,…,In }.实验Ej 需要用到的仪器是I的子集Rj∈I.配置仪器Ik 的费用为ck 美元.实验Ej