This is the same as soj 3109, but it requires a higher level of requirements and provides a selection scheme.
For each component, the Source Vertex connects an edge with a capacity at its cost. For each product, the Source Vertex connects an edge with a capacity of its value.
After the minimum cut is obtained, if (I, T) is full, it must be the cut edge. It indicates that the product is definitely not selected. If (S, I) is full, it is not necessarily a cut edge, but if the cut edge is in the form of (S, I), it must be full stream, And I represents the element must be selected
It can be understood that if (I, T) is full, it means that the profit of product I is less than or equal to 0, and there is no profit, because the cost of the components that make it has offset the profit, in the components related to it, the edges connected to the source point may be full streams or not full streams, but as long as one side is not full streams, none of these edges will be cut edges, as long as there is a non-full stream, in the residual network, the source point can reach the point represented by this product, through this point, you can reach the vertices that are related to it and are connected to the source point in full flow (that is, the vertices represented by the components it needs). Otherwise, if (I, t) if there is no full stream, it indicates that the product can generate profit, and the source point is full stream to the edges of the component vertex required for production. All these edges are cut edges.
Therefore, in the smallest cut edge, if it is related to S, the corresponding component will be purchased. If it is related to T, the product will not be manufactured.
C [s, s'] = sum (I) + sum (J), I is the purchased component, and J is the product that will not be manufactured
If total is the sum of values of all products, total-sum (I)-sum (j) = total-C [s, s'] (minimum cut capacity ), maximum Profit
When the final result is output, first find out which products need to be manufactured (the edge of the product is not full of the stream with the sink point ), then find out the components required to make the product (the edge of the source point is full and associated with the manufactured product)
I made a lot of compilation errors on zoj for the first time...
Code:
# Include <memory. h> <br/> # include <string. h> <br/> # include <stdio. h> <br/> # include <iostream> <br/> using namespace STD; <br/> # define maxn 400 <br/> # define maxl 400 <br/> # define INF 1 <30 <br/> struct node <br/> {<br /> int V, c, next; <br/>} G [maxn * maxn]; <br/> int dis [maxn], num [maxn], pre [maxn], cur [maxn], adj [maxn], RES1 [maxn], RES2 [maxn]; <br/> char list [maxl] [50]; <br/> int s, t, vn, E; <br/> void addedge (int u, int V, int c) <br/>{< br/> G [e]. V = V; G [e]. C = C; G [e]. next = adj [u]; adj [u] = e ++; <br/> G [e]. V = u; G [e]. C = 0; G [e]. next = adj [v]; adj [v] = e ++; <br/>}< br/> int find (char name [50]) <br/> {<br/> for (INT I = 1; I <maxl; I ++) <br/>{< br/> If (strcmp (list [I], name) = 0) <br/> return I; <br/>}< br/> return 0; <br/>}< br/> int SAP () <br/>{< br/> int I, U, v, flow = 0, Aug = inf, flag; <br/> for (I = 0; I <= Vn; I ++) <br/> {<br/> dis [I] = num [I] = 0; <br/> Cu R [I] = adj [I]; <br/>}< br/> num [0] = Vn; <br/> pre [s] = u = s; <br/> while (DIS [s] <VN) <br/>{< br/> flag = 0; <br/> for (I = cur [u]; i! =-1; I = G [I]. next) <br/> {<br/> V = G [I]. v; <br/> If (G [I]. C & dis [u] = dis [v] + 1) <br/> {<br/> flag = 1; <br/> pre [v] = u; <br/> cur [u] = I; <br/> Aug = Aug <G [I]. c? Aug: G [I]. c; <br/> U = V; <br/> If (u = T) <br/>{< br/> flow ++ = Aug; <br/> while (u! = S) <br/>{< br/> U = pre [u]; <br/> G [cur [u]. c-= Aug; <br/> G [cur [u] ^ 1]. c + = Aug; <br/>}< br/> Aug = inf; <br/>}< br/> break; <br/>}< br/> If (FLAG) <br/> continue; <br/> If (-- num [dis [u] = 0) <br/> break; <br/> for (DIS [u] = Vn, I = adj [u]; I! =-1; I = G [I]. next) <br/> {<br/> V = G [I]. v; <br/> If (G [I]. C & dis [v] <dis [u]) <br/>{< br/> dis [u] = dis [v]; <br/> cur [u] = I; <br/>}< br/> dis [u] ++; <br/> num [dis [u] ++; <br/> U = pre [u]; <br/>}< br/> return flow; <br/>}< br/> int main () <br/> {<br/> int I, j, N, order, component, cost, value, listnumber, cnt1, cnt2, sum; <br/> char name [50]; <br/> scanf ("% d", & N); <br/> while (n --) <br/>{< br/> memset (list, 0, sizeof (list); <br/> Memset (adj,-1, sizeof (adj); <br/> E = 0; <br/> S = 0; <br/> scanf ("% d", & component); <br/> for (I = 1; I <= component; I ++) <br/>{< br/> scanf ("% S % d", & name, & cost); <br/> strcpy (list [I], name ); <br/> addedge (S, I, cost); <br/>}< br/> scanf ("% d", & order ); <br/> T = component + order + 1; <br/> VN = t + 1; <br/> sum = 0; <br/> for (I = 1; I <= order; I ++) <br/>{< br/> scanf ("% S % d", & name, & Value, & J ); <br/> sum + = value; <br/> strcpy (list [component + I], Name); <br/> addedge (Component + I, T, value); <br/> while (j --) <br/>{< br/> scanf ("% s", & name); <br/> listnumber = find (name); <br/> addedge (listnumber, component + I, INF); <br/>}< br/> printf ("% d/N", Sum-SAP ()); <br/> cnt1 = cnt2 = 0; <br/> for (I = component + 1; I <= component + order; I ++) <br/>{< br/> for (j = adj [I]; J! =-1; j = G [J]. next) <br/> {<br/> If (G [J]. V = T) <br/>{< br/> If (G [J]. c) <br/> RES1 [cnt1 ++] = I; // Save the product to be manufactured <br/> break; <br/>}< br/> for (I = 0; I <cnt1; I ++) <br/>{< br/> for (j = adj [RES1 [I]; J! =-1; j = G [J]. next) <br/> {<br/> If (G [J]. v <= component) <br/> RES2 [cnt2 ++] = G [J]. v; // Save the components required for the manufacturing product <br/>}< br/> printf ("% d/N", cnt1 ); <br/> for (I = 0; I <cnt1; I ++) <br/> printf ("% s/n", list [RES1 [I]); <br/> printf ("% d/N", cnt2); <br/> for (I = 0; I <cnt2; I ++) <br/> printf ("% s/n", list [RES2 [I]); <br/> printf ("/N "); <br/>}< br/> return 0; <br/>}