1. 程式人生 > >網絡流24T 太空飛行計劃問題

網絡流24T 太空飛行計劃問題

數據 bool get turn 教授 scan 題目 for 需要

題目背景

題目描述

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

最大權閉合子圖
挺裸的建模
這題目需要spj啊
所以不要去沒spj的題庫啊比如說codevs?
#include<cstdio>
#include
<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn = 110000; const int INF = 0x7fffffff; int n,m,S,T; struct node{ int next,v,w; }edge[maxn]; int dis[maxn]; int que[maxn],head[maxn]; int num=1; void add_edge(int u,int v,int w) { edge[
++num].v=v;edge[num].w=w;edge[num].next=head[u];head[u]=num; edge[++num].v=u;edge[num].w=0; edge[num].next=head[v];head[v]=num; } bool bfs() { memset(dis,-1,sizeof(dis)); int h=0,t=1; que[h]=dis[0]=0; while(h<t) { int u=que[h++]; if(h==maxn)h=0; for(int i=head[u];i;i=edge[i].next) { int v=edge[i].v; if(edge[i].w&&dis[v]<0) { que[t++]=v; dis[v]=dis[u]+1; if(t==maxn)t=0; } } } if(dis[T]==-1)return false; return true; } int dfs(int x,int f) { if(x==T) return f; int mn=0,w; for(int i=head[x];i;i=edge[i].next) { if(edge[i].w&&dis[edge[i].v]==dis[x]+1) { w=f-mn; w=dfs(edge[i].v,min(w,edge[i].w)); edge[i].w-=w; edge[i^1].w+=w; mn+=w; if(mn==f)return f; } } if(!mn)dis[x]=-1; return mn; } int main(){ int sum=0; scanf("%d%d",&m,&n);S=0,T=n+m+1; for(int a,i=1;i<=m;++i) { bool flag=0; scanf("%d",&a);sum+=a; add_edge(S,i,a); while(11101001) { int x=0; char c=getchar(); while(c<0||c>9) c=getchar(); while(c<=9&&c>=0){x=x*10+c-0,c=getchar();} add_edge(i,x+m,INF);if(c==10||c==13)break; } } for(int a,i=1;i<=n;++i) scanf("%d",&a),add_edge(m+i,T,a); int ans=0; while(bfs()) ans+=dfs(S,INF); for(int i=1;i<=m;++i) if(dis[i]!=-1)printf("%d ",i); puts(""); for(int i=m+1;i<=T;i++) if(dis[i]!=-1)printf("%d ",i-m); puts(""); printf("%d\n",sum-ans); return 0; }

網絡流24T 太空飛行計劃問題