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