NYIST 531 太空飞行计划
太空飞行计划
时间限制:1000 ms | 内存限制:65535 KB
难度:4
- 描述
-
W 教授正在为国家航天中心计划一系列的太空飞行。每次太空飞行可进行一系列商业性实验而获取利润。现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的集合I={I1,I2,…In}。实验Ej需要用到的仪器是I的子集Rj 。配置仪器Ik的费用为ck美元。实验Ej的赞助商已同意为该实验结果支付pj美元。W教授的任务是找出一个有效算法,确定在一次太空飞行中要进行哪些实验并因此而配置哪些仪器才能使太空飞行的净收益最大。这里净收益是指进行实验所获得的全部收入与配置仪器的全部费用的差额。对于给定的实验和仪器配置情况,编程找出净收益最大的试验计划。
- 输入
- 多组测试数据(不超过500组)
每组数据第1行有2 个正整数m和n(m,n <= 100)。m是实验数,n是仪器数。接下来的m 行,每行是一个实验的有关数据。第一个数赞助商同意支付该实验的费用f(f < 10000);接着是该实验需要用到的仪器的个数t,接着是t个仪器的编号。最后一行的n个数是配置每个仪器的费用pi(pi <=100)。 - 输出
- 每组数据输出占一行,输出最大的净收益(如果无法收益,输出0)。
- 样例输入
-
2 3 10 2 1 2 25 2 2 3 5 6 7
- 样例输出
-
17
- 上传者
- ACM_杨延玺
- 解题:最大权闭合子图,输入真尼玛蛋疼,好吧,原来的那个题,有几组数据貌似有问题。南阳这个只需要输出最大权值就是了,不需要输出实验编号以及仪器编号
-
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <climits> 7 #include <vector> 8 #include <queue> 9 #include <cstdlib> 10 #include <string> 11 #include <set> 12 #include <stack> 13 #define LL long long 14 #define pii pair<int,int> 15 #define INF 0x3f3f3f3f 16 using namespace std; 17 const int maxn = 500; 18 struct arc{ 19 int to,flow,next; 20 arc(int x = 0,int y = 0,int z = -1){ 21 to = x; 22 flow = y; 23 next = z; 24 } 25 }; 26 arc e[maxn*maxn]; 27 int head[maxn],d[maxn],cur[maxn]; 28 int tot,m,n,S,T; 29 void add(int u,int v,int flow){ 30 e[tot] = arc(v,flow,head[u]); 31 head[u] = tot++; 32 e[tot] = arc(u,0,head[v]); 33 head[v] = tot++; 34 } 35 bool bfs(){ 36 memset(d,-1,sizeof(d)); 37 d[S] = 1; 38 queue<int>q; 39 q.push(S); 40 while(!q.empty()){ 41 int u = q.front(); 42 q.pop(); 43 for(int i = head[u]; ~i; i = e[i].next){ 44 if(e[i].flow && d[e[i].to] == -1){ 45 d[e[i].to] = d[u] + 1; 46 q.push(e[i].to); 47 } 48 } 49 } 50 return d[T] > -1; 51 } 52 int dfs(int u,int low){ 53 if(u == T) return low; 54 int tmp = 0,a; 55 for(int &i = cur[u]; ~i; i = e[i].next){ 56 if(e[i].flow && d[e[i].to] == d[u] + 1 &&(a=dfs(e[i].to,min(e[i].flow,low)))){ 57 e[i].flow -= a; 58 e[i^1].flow += a; 59 tmp += a; 60 low -= a; 61 if(!low) break; 62 } 63 } 64 if(!tmp) d[u] = -1; 65 return tmp; 66 } 67 int dinic(){ 68 int ans = 0; 69 while(bfs()){ 70 memcpy(cur,head,sizeof(head)); 71 ans += dfs(S,INF); 72 } 73 return ans; 74 } 75 void go(int u){ 76 char str[maxn]; 77 gets(str); 78 for(int i = 0; str[i];){ 79 while(str[i] &&(str[i] < '0' || str[i] > '9')) ++i; 80 int x = 0; 81 while(str[i] && str[i] >= '0' && str[i] <= '9'){ 82 x = x*10 + str[i++] - '0'; 83 } 84 if(x) add(u,x+m,INF); 85 } 86 } 87 bool vis[maxn]; 88 vector<int>ans1,ans2; 89 void dfs(int u){ 90 vis[u] = true; 91 for(int i = head[u]; ~i; i = e[i].next){ 92 if(vis[e[i].to] || e[i].flow == 0) continue; 93 if(e[i].to > m) ans2.push_back(e[i].to-m); 94 else ans1.push_back(e[i].to); 95 dfs(e[i].to); 96 } 97 } 98 bool cmp(int a,int b){ 99 return a > b; 100 } 101 int main() { 102 int w; 103 while(~scanf("%d %d",&m,&n)){ 104 memset(head,-1,sizeof(head)); 105 int ans = S = tot = 0; 106 T = n + m + 1; 107 ans1.clear(); 108 ans2.clear(); 109 for(int i = 1; i <= m; ++i){ 110 scanf("%d",&w); 111 add(S,i,w); 112 ans += w; 113 go(i); 114 } 115 for(int i = 1; i <= n; ++i){ 116 scanf("%d",&w); 117 add(m+i,T,w); 118 } 119 ans -= dinic(); 120 /*memset(vis,false,sizeof(vis)); 121 dfs(S); 122 sort(ans1.begin(),ans1.end(),cmp); 123 sort(ans2.begin(),ans2.end(),cmp); 124 for(int i = ans1.size()-1; i >= 0; --i) 125 printf("%d%c",ans1[i],i?' ':'\n'); 126 for(int i = ans2.size()-1; i >= 0; --i) 127 printf("%d%c",ans2[i],i?' ':'\n');*/ 128 printf("%d\n",ans); 129 } 130 return 0; 131 }
夜空中最亮的星,照亮我前行