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?' ':'
');
126         for(int i = ans2.size()-1; i >= 0; --i)
127             printf("%d%c",ans2[i],i?' ':'
');*/
128         printf("%d
",ans);
129     }
130     return 0;
131 }
View Code
原文地址:https://www.cnblogs.com/crackpotisback/p/4057741.html