zoj2071:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2071
题意:题意一些零件,每一个零件会有一个花费,然后用这些的零件可以生产一些产品,产品可以卖出一些钱,现在问你这些零件可以专区的额最大花费。
题解:零件和源点建立一边,容量为零件的费用,然后产品和汇点建立边,容量为产品的价值,然后零件盒产品之间建立相应的边,容量为INF,然后跑网络流,如果某产品和汇点之间的满流,说明,生产这样的产品赚取的费用是0,所以这样的产品是可以不成产的,所以,只要统计没有满流的安歇边就可以了。同时,这里的零件是可以购买多次的,也就是说,你可以买两个以上的相同零件用于生产不同的产品。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }