Everyone else said it was a bare minimum charge stream. After thinking for a long time, I couldn't think of how to do it. I finally understood it after reading other people's problem-solving reports.
The key lies in the composition and conversion. The source point is 1. Add a sink point. The edge capacity of the sink point to each city is the opposite of the money that each city sells beer. Use spfa to find the shortest path of the cost. If the cost of the shortest path is smaller than 0, it indicates that this path is profitable; otherwise, it is at a loss,AlgorithmStop.
# Include <iostream> # include <queue> # include <cstdio> # include <cstring> using namespace STD; const int n = 105; const int M = 2005; const int INF = 1000000000; struct edge {int V; int cap; int cost; int next ;}; edge e [M * 4 + N * 2]; int head [N]; int cost [N]; int pre_v [N], pre_e [N]; bool INQ [N]; int n, m; int CNT; void add_edge (int u, int V, int cap, int cost) {e [CNT]. V = V; E [CNT]. CAP = CAP; E [CNT]. cost = cost; E [CNT]. next = Head [u]; head [u] = CNT ++; E [CNT]. V = u; E [CNT]. CAP = 0; E [CNT]. cost =-cost; E [CNT]. next = head [v]; head [v] = CNT ++;} int mcmf (int s, int T, int N) {queue <int> q; int U; int mincost = 0; while (1) {memset (INQ, false, sizeof (INQ); // memset (pre_e,-1, sizeof (pre_e )); memset (pre_v,-1, sizeof (pre_v); q. push (s); For (INT I = 0; I <n; I ++) cost [I] = inf; cost [s] = 0; INQ [s] = true; // spfa // calculate the shortest path while (! Q. Empty () {u = Q. Front (); q. Pop (); INQ [u] = false; For (INT I = head [u]; I! =-1; I = E [I]. next) {int v = E [I]. v; If (E [I]. cap & cost [u] + E [I]. cost <cost [v]) {cost [v] = cost [u] + E [I]. cost; If (! INQ [v]) {q. push (V); INQ [v] = true;} pre_v [v] = u; pre_e [v] = I ;}}} // when the cost [T] is greater than 0, it indicates that the current transaction is at a loss. Exit if (cost [T]> = 0) break; int F = inf; for (INT I = T; I! = S; I = pre_v [I]) {int v = pre_e [I]; F = min (F, E [v]. CAP);} mincost + = f * cost [T]; for (INT I = T; I! = S; I = pre_v [I]) {int u = pre_e [I]; E [u]. cap-= f; E [U ^ 1]. cap + = f ;}} return-mincost;} int main () {int U, V, Cap, W; while (CIN> N> m) {If (! N &&! M) break; CNT = 0; memset (Head,-1, sizeof (head); For (INT I = 2; I <= N; I ++) {scanf ("% d", & W); add_edge (I, n + 1, INF,-W) ;}for (INT I = 0; I <m; I ++) {scanf ("% d", & U, & V, & Cap, & W); add_edge (u, v, cap, w); add_edge (v, U, Cap, W) ;}cout <mcmf (1, n + 1, n + 2) <Endl ;}return 0 ;}