Questions B of last year's invitational call competition, there were so few calls at that time... Is it a very bare and feasible stream with the minimum flow .. You only need to find the minimum feasible stream for each person separately. Creating a graph is to split each vertex and set the capacity to V [I] in the next step. Then, you can directly connect the edge between each vertex. Then, on the basis of this graph, convert it to the smallest stream of the feasible stream. Just find it...
# Include <algorithm> # include <iostream> # include <cstring> # include <vector> # include <cstdio> # include <cmath> # include <queue> # include <stack> # include <map> # include <set> # define ll long # define INF 0x3f3f3f # define CLR (, b) memset (a, B, sizeof (A) using namespace STD; const int maxn = 440; const int INF = 0x3f3f3f; struct edge {int from, to, cap, flow; edge () {} edge (int from, int to, int cap, int flow): FR OM (from), to (to), Cap (CAP), flow (flow) {}}; struct ISAP {int n, m, S, T; vector <edge> edges; vector <int> G [maxn]; // adjacent table, G [I] [J] indicates the number of the J edge of node I in the E array bool vis [maxn]; // BFS uses int d [maxn]; // The distance from the start point to I int cur [maxn]; // The Current Arc pointer int P [maxn]; // The Last arc int num [maxn] On the augmented path; // void addedge (int from, int to, int cap) {edges. push_back (edge (from, to, Cap, 0); edges. push_back (edge (to, from, 0, 0); M = ed GES. size (); G [from]. push_back (m-2); G [to]. push_back m-1);} bool BFS () {memset (VIS, 0, sizeof (VIS); queue <int> q; q. push (t); vis [T] = 1; d [T] = 0; while (! Q. empty () {int x = Q. front (); q. pop (); For (INT I = 0; I <G [X]. size (); I ++) {edge & E = edges [G [x] [I] ^ 1]; If (! Vis [E. from] & E. cap> E. flow) {vis [E. from] = 1; d [E. from] = d [x] + 1; q. push (E. from) ;}}return vis [s];} void Init (int n) {This-> N = N; For (INT I = 0; I <N; I ++) g [I]. clear (); edges. clear () ;}int augment () {int x = T, A = inf; while (X! = S) {edge & E = edges [p [x]; A = min (A, E. cap-e.flow); X = edges [p [X]. from;} X = T; while (X! = S) {edges [p [x]. flow + = A; edges [p [x] ^ 1]. flow-= A; X = edges [p [x]. from;} return a;} int maxflow (int s, int T, int need) {This-> S = s; this-> T = T; int flow = 0; BFS (); memset (Num, 0, sizeof (Num); For (INT I = 0; I <n; I ++) num [d [I] ++; int x = s; memset (cur, 0, sizeof (cur); While (d [s] <n) {If (x = T) {flow + = augment (); If (flow> = need) return flow; X = s;} int OK = 0; for (INT I = cur [X]; I <G [X]. size (); I ++) {edge & E = edges [G [x] [I]; If (E. cap> E. flow & D [x] = d [E. to] + 1) // advance {OK = 1; p [E. to] = G [x] [I]; cur [x] = I; // note that X = E. to; break ;}} if (! OK) // retreat {int M = n-1; // Initial Value Note for (INT I = 0; I <G [X]. size (); I ++) {edge & E = edges [G [x] [I]; If (E. cap> E. flow) M = min (M, d [E. to]);} If (-- num [d [x] = 0) break; num [d [x] = m + 1] ++; cur [x] = 0; // note that if (X! = S) x = edges [p [x]. from ;}} return flow ;}} Sol; int n, m; struct point {int X, Y, B, E; int V [7]; void inpt () {scanf ("% d", & X, & Y, & B, & E); e + = B; For (INT I = 0; I <m; I ++) scanf ("% d", & V [I]) ;}} P [maxn]; bool OK (point a, point B) {int Len = (. x-B. x) * (. x-B. x) + (. y-B. y) * (. y-B. y); return B. b>. E & Len <= (B. b-. e) * (B. b-. e);} int solve (INT idx) {Sol. init (N * 2 + 5 ); Int S = 0, T = 2 * n + 1, SS = 2 * n + 2, St = SS + 1; for (INT I = 1; I <= N; I ++) {// Sol. addedge (I, I + N, 0); Sol. addedge (S, I, INF); Sol. addedge (I + N, T, INF); Sol. addedge (SS, I + N, P [I]. V [idx]); Sol. addedge (I, St, P [I]. V [idx]) ;}for (INT I = 1; I <= N; I ++) for (Int J = 1; j <= N; j ++) {If (! OK (P [I], p [J]) continue; Sol. addedge (I + N, J, P [I]. V [idx]);} Sol. maxflow (SS, St, INF); Sol. addedge (t, s, INF); Sol. maxflow (SS, St, INF); Return Sol. edges [Sol. edges. size ()-2]. flow;} int main () {int t; scanf ("% d", & T); While (t --) {scanf ("% d", & N, & M); n --; scanf ("% d", & P [0]. x, & P [0]. y); P [0]. B = P [0]. E = 0; For (INT I = 1; I <= N; I ++) P [I]. inpt (); int ans = 0; For (INT I = 0; I <m; I ++) ans + = solve (I ); printf ("% d \ n", ANS );}}
HDU 4494 teamwork (the smallest stream of feasible streams)