zoj2071:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2071ios
題意:題意一些零件,每個零件會有一個花費,而後用這些的零件能夠生產一些產品,產品能夠賣出一些錢,如今問你這些零件能夠專區的額最大花費。網絡
題解:零件和源點創建一邊,容量爲零件的費用,而後產品和匯點創建邊,容量爲產品的價值,而後零件盒產品之間創建相應的邊,容量爲INF,而後跑網絡流,若是某產品和匯點之間的滿流,說明,生產這樣的產品賺取的費用是0,因此這樣的產品是能夠不成產的,因此,只要統計沒有滿流的安歇邊就能夠了。同時,這裏的零件是能夠購買屢次的,也就是說,你能夠買兩個以上的相同零件用於生產不一樣的產品。ide
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\n",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\n",top);sum2=0; 116 for(int i=1;i<=top;i++){ 117 printf("%s\n",num[ans[i]].str); 118 sum2+=num[ans[i]].t; 119 } 120 printf("%d\n",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\n",num[ans[i]].ss[j]); 125 } 126 } 127 return 0; 128 }