NKOI 1937 太空飞行计划

【线性规划与网络流24题 2】太空飞行计划

Time Limit:10000MS  Memory Limit:65536K
Total Submit:36 Accepted:13 
Case Time Limit:1000MS

Description

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

由于本OJ无Special Judge , 所以只需要输出最多能得到的净获利。

Input

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

Output

一行,包含一个整数,表示最大净收益

Sample Input

2 3
10 1 2
25 2 3
5 6 7

Sample Output

17

Source

感谢 Wo_ai_WangYuan 修改题目并放上数据


这道题需要我们来转一个弯

首先我们求的是最大利益,这个利益应该是sum{c[i]}-sum{p[j]} 的最大值,其中i是被选中的实验,j是需要的仪器

因此我们应该求出sum{c[k]}+sum{p[j]}的最小值,其中k是未被选中的实验

这里我们应该求的是最小割,因为删除了这些边,整个图都是不连通的

#include<cstdio>
#include<iostream>
using namespace std;
const int maxn=105,inf=1e9;
int n,m,g[maxn][maxn],op,ed;
int dis[maxn],vd[maxn];
string ss;
int dfs(int u,int flow){  
    if(u==ed)return flow;  
    int v,temp,delta=0;  
    for(v=1;v<=ed;v++)  
        if(g[u][v]&&dis[u]==dis[v]+1){  
            temp=dfs(v,min(flow-delta,g[u][v]));  
            g[u][v]-=temp;  
            g[v][u]+=temp;  
            delta+=temp;  
            if(delta==flow||dis[op]>=ed)return delta;  
        }  
    if(dis[op]>=ed)return delta;  
    vd[dis[u]]--;  
    if(vd[dis[u]]==0)dis[op]=ed;  
    dis[u]++;  
    vd[dis[u]]++;  
    return delta;  
}  
int main(){
	cin>>m>>n;
	int i,j,temp=0,sum=0;
	op=n+m+1,ed=op+1;
	for(i=1;i<=m;i++){
		cin>>g[op][i];
		sum+=g[op][i];
		getline(cin,ss);
		ss+=" ";
		temp=0;
		for(j=1;j<ss.length();j++){
			if(ss[j]==' '){
				g[i][temp+m]=inf;
				temp=0;
			}
			else temp=temp*10+ss[j]-'0';
		}
	}
	for(i=1;i<=n;i++)cin>>g[i+m][ed];
	int ans=0;
	while(dis[op]<ed)ans+=dfs(op,inf);
	cout<<sum-ans;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值