Hdoj 4971 A simple brute force problem. [maximum weight closure diagram, hdoj4971
Question: hdoj 4971 A simple brute force problem.
Question:Given n tasks and m technologies, several technologies are required to complete a task. To complete a task, you have a bonus. Learning a technology requires money,There is a parent-child relationship between technologies. A technology may need to learn other technologies first,Then, how many tasks do you choose to achieve the greatest benefit?
Analysis:
Some related definitions:
Closed graph:All vertices allIn this graph, it is called a closed graph. (That is, the successor vertices in the graph are all in the graph, and there are few definitions on the Internet)
Max weight closed graph: the vertex and largest closed graph, that is, each vertex has a weight value, which may be a negative value. Find a subclosed graph of the closed graph to maximize its weight.
One of the classic questions on the Internet is the space flight plan. You can ask du Niang on your own. In fact, the meaning is the same as that in the blacklist.
Max weight closure Graphic Method: Network Flow
Set a super source point S to connect all normal values
The traffic is a positive weight, and all negative values are connected to the super settlement point T,
Capacity is the absolute value of negative weight, and an edge is created when an edge exists between the positive weight and negative weight. The capacity is infinite ,,
Then the maximum closing Weight = positive weight and-least cut (maximum Stream)
After reading the definition above, I think it is very simple. Reading the black text of the question is a matter of standard closing right. The key to this question is the relationship between technologies, many people think of dp and tree-like dp.
In fact, it is a closed-Permission question template. The official question is: if there is a mutual relationship between technologies, it needs to be scaled down. In fact, it does not need to be scaled down, that is, the capacity of the edge to be created between correlated points is infinite.
AC code: 46 ms
# Include <cstdio> # include <algorithm> # include <vector> # include <queue> # include <cstring> const int N = 200; using namespace std; const int inf = 0x3f3f3f; # define Del (a, B) memset (a, B, sizeof (a) struct Node {int from, to, cap, flow ;}; vector <int> v [N]; vector <Node> e; int vis [N], cur [N]; void add_Node (int from, int to, int cap) {e. push_back (Node) {from, to, cap, 0}); e. push_back (Node) {to, from, 0, 0}); int tmp = e. size (); V [from]. push_back (tmp-2); v [to]. push_back (tmp-1);} bool bfs (int s, int t) {Del (vis,-1); queue <int> q; q. push (s); vis [s] = 0; while (! Q. empty () {int x = q. front (); q. pop (); for (int I = 0; I <v [x]. size (); I ++) {Node tmp = e [v [x] [I]; if (vis [tmp. to] <0 & tmp. cap> tmp. flow) // The second condition ensures {vis [tmp. to] = vis [x] + 1; q. push (tmp. to) ;}}} if (vis [t]> 0) return true; return false;} int dfs (int o, int f, int t) {if (o = t | f = 0) // returns f; int a = 0, ans = 0; for (int & I = cur [o]; I <v [o]. size (); I ++) // note the preceding '&', which is an important optimization {Node & tmp = e [v [o] [I]; if (vis [tmp. to] = (vis [o] + 1) & (a = dfs (tmp. to, min (f, tmp. cap-tmp.flow), t)> 0) {tmp. flow + = a; e [v [o] [I] ^ 1]. flow-= a; // save graph mode ans + = a; f-= a; if (f = 0) // note break optimization;} return ans; // optimization} int dinci (int s, int t) {int ans = 0; while (bfs (s, t) {Del (cur, 0 ); int tm = dfs (s, inf, t); ans + = tm;} return ans;} void v_clear (int n) {for (int I = 0; I <= n; I ++) v [I]. clear (); e. clear () ;}int main () {// freopen ("Input.txt", "r", stdin); int T; scanf ("% d", & T ); for (int cas = 1; cas <= T; cas ++) {int n, m, sum = 0; scanf ("% d", & n, & m); int s = 0, t = n + m + 1, x; for (int I = 1; I <= n; I ++) scanf ("% d", & x), add_Node (s, I, x), sum + = x; for (int I = 1; I <= m; I ++) scanf ("% d", & x), add_Node (n + I, t, x); for (int I = 1; I <= n; I ++) {scanf ("% d", & x); while (x --) {int tmp; scanf ("% d", & tmp); add_Node (I, n + tmp + 1, inf) ;}}for (int I = 1; I <= m; I ++) {for (int j = 1; j <= m; j ++) {scanf ("% d", & x); if (x) add_Node (n + I, n + j, inf );}} printf ("Case # % d: % d \ n", cas, sum-dinci (s, t); v_clear (t) ;}return 0 ;}