Technology Trader

zoj2071:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2071

题意:题意一些零件,每一个零件会有一个花费,然后用这些的零件可以生产一些产品,产品可以卖出一些钱,现在问你这些零件可以专区的额最大花费。

题解:零件和源点建立一边,容量为零件的费用,然后产品和汇点建立边,容量为产品的价值,然后零件盒产品之间建立相应的边,容量为INF,然后跑网络流,如果某产品和汇点之间的满流,说明,生产这样的产品赚取的费用是0,所以这样的产品是可以不成产的,所以,只要统计没有满流的安歇边就可以了。同时,这里的零件是可以购买多次的,也就是说,你可以买两个以上的相同零件用于生产不同的产品。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cstdio>
  5 #include<queue>
  6 #include<map>
  7 #define INF 100000000
  8 using namespace std;
  9 const int N=405;
 10 const int M=10000;
 11 struct Node{
 12    int v;
 13    int f;
 14    int next;
 15 }edge[M];
 16 int n,m,u,v,cnt,sx,ex;
 17 int head[N],pre[N];
 18 int ans[N],top;
 19 struct Edge{
 20   char str[35];
 21   int  t;
 22   int val;
 23   char ss[100][35];
 24 }num[N];
 25 void init(){
 26     cnt=0;
 27     memset(head,-1,sizeof(head));
 28 }
 29 void add(int u,int v,int w){
 30     edge[cnt].v=v;
 31     edge[cnt].f=w;
 32     edge[cnt].next=head[u];
 33     head[u]=cnt++;
 34     edge[cnt].f=0;
 35     edge[cnt].v=u;
 36     edge[cnt].next=head[v];
 37     head[v]=cnt++;
 38 }
 39 bool BFS(){
 40   memset(pre,0,sizeof(pre));
 41   pre[sx]=1;
 42   queue<int>Q;
 43   Q.push(sx);
 44  while(!Q.empty()){
 45      int d=Q.front();
 46      Q.pop();
 47      for(int i=head[d];i!=-1;i=edge[i].next    ){
 48         if(edge[i].f&&!pre[edge[i].v]){
 49             pre[edge[i].v]=pre[d]+1;
 50             Q.push(edge[i].v);
 51         }
 52      }
 53   }
 54  return pre[ex]>0;
 55 }
 56 int dinic(int flow,int ps){
 57     int f=flow;
 58      if(ps==ex)return f;
 59      for(int i=head[ps];i!=-1;i=edge[i].next){
 60         if(edge[i].f&&pre[edge[i].v]==pre[ps]+1){
 61             int a=edge[i].f;
 62             int t=dinic(min(a,flow),edge[i].v);
 63               edge[i].f-=t;
 64               edge[i^1].f+=t;
 65             flow-=t;
 66              if(flow<=0)break;
 67         }
 68 
 69      }
 70       if(f-flow<=0)pre[ps]=-1;
 71       return f-flow;
 72 }
 73 int  solve(){
 74     int sum=0;
 75     while(BFS())
 76         sum+=dinic(INF,sx);
 77    return sum;
 78 }
 79 char temp[100];
 80 int main() {
 81     int T,k,sum1,sum2,t1,tt=1;
 82     scanf("%d",&T);
 83     while(T--) {
 84          if(tt>1)puts("");
 85        tt=2;
 86          scanf("%d",&n);
 87          init();
 88          map<string,int>mp1;
 89       for(int i=1;i<=n;i++){
 90           scanf("%s%d",temp,&t1);
 91           mp1[temp]=i;
 92           add(0,i,t1);
 93       }
 94        scanf("%d",&m);sum1=0;
 95       for(int i=1;i<=m;i++){
 96           scanf("%s%d%d",num[i].str,&t1,&num[i].t);
 97           mp1[num[i].str]=i+n;
 98           num[i].val=t1;
 99           sum1+=t1;
100           add(i+n,n+m+1,t1);
101           for(int j=1;j<=num[i].t;j++){
102              scanf("%s",num[i].ss[j]);
103              add(mp1[num[i].ss[j]],i+n,INF);
104           }
105       }
106       sx=0;ex=n+m+1;top=0;
107     printf("%d
",sum1-solve());
108       for(int i=n+1;i<=n+m;i++){
109           for(int j=head[i];j!=-1;j=edge[j].next){
110               if(edge[j].f>0&&edge[j].v==n+m+1){
111                  ans[++top]=i-n;
112               }
113           }
114       }
115      printf("%d
",top);sum2=0;
116      for(int i=1;i<=top;i++){
117         printf("%s
",num[ans[i]].str);
118         sum2+=num[ans[i]].t;
119      }
120      printf("%d
",sum2);
121      for(int i=1;i<=top;i++){
122         int ttt=num[ans[i]].t;
123         for(int j=1;j<=ttt;j++)
124             printf("%s
",num[ans[i]].ss[j]);
125      }
126     }
127     return 0;
128 }
View Code
原文地址:https://www.cnblogs.com/chujian123/p/3955456.html