(Click here to view the original title)
Analysis of the meaning of problems
Gives the n nodes, there is a minimum flow and a maximum flow rate m of conduits, each conduit, and the inflow amount of each node is equal to the outflow flows, asking nodes n and m can form a pipeline flow circulation
Problem-solving ideas
The classic passive exchange viable flow problems up and down the border, because each side there is a minimum and maximum flow rate low flow rate up, so each side has at least low traffic, we have set up this initial flow rate for each side, so we lower bound on all sides can be changed to 0, the upper bound to become up-low, equivalent to the elimination of the lower bound, and up-low, said a similar capacity of this edge, and the general maximum flow problem, it will be that there are upper and lower bounds side into a capacity of up-low side
And this kind of problem is not the source and sink, then we'll build a pair of source point to sink point.
The upper and lower bounds deal with the problem, we also need to address other core issues: the inflow of each point is equal to outflow, because we each edge assigned an initial flow rate, then for each point, there is an initial amount of inflow and outflow the initial amount of the initial inflow outflow -i point difference between a [i] = i point
1) If a [i]> 0, excessive inflow description, the inflow amount deemed excess inflow source, i.e., from the source node to build a capacity of i a [i] edge
2) If a [i] <0, described excessive output, then the excess flow amount flowing into the sink is considered, i.e., the i sink to build a capacity | A [i] | edge
We recorded S_OUT total outflow source point, if the maximum flow max_flow constructed in FIG == s_out, a picture illustrating a process flow into and flows out to the sink s, no traffic is lost, it is the flow picture circulation, and in the process of seeking the maximum flow, we have the capacity to adjust each side well, that condition is satisfied, then the actual flow of each side is the lower bound of the actual flow +
Code area
(ZOJ temporarily can not pay because of this problem, so I was using someone else's nominal after a long shot, the resulting code if ZOJ repair, I will be given through the evaluation of the code)
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<string> #include<fstream> #include<vector> #include<stack> #include <map> #include <iomanip> #define bug cout << "**********" << endl #define show(x, y) cout<<"["<<x<<","<<y<<"] " #define LOCAL = 1; using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f ; const LL + 1E9 = MOD . 7 ; const int Max 1E5 + = 10 ; const int Max2 = 3e2 + 10 ; struct Edge { int to, Flow, Next; } Edge [Max << . 1 ]; int n-, m, S, T; int head [Max], TOT; int DIS [Max], CUR [Max]; int a [Max]; // record the initial i inflow stream - outflow int in [Max]; / / in the recording initial flow duct, i.e. the lower bound; int ID [Max]; // record the reverse side pipe number i in the residual network void the init () { Memset (head, - . 1 , the sizeof (head)); TOT = 0 ; Memset (A, 0 , the sizeof (A)); S = 0 ; T = n-+ . 1 ; } void the Add ( int U, int V, int Flow) { Edge [TOT] .to = V; Edge [TOT] .flow = Flow; Edge [TOT] .next = head [U ]; head[u] = tot++; } bool bfs() { memset(dis,-1,sizeof(dis)); queue<int>q; dis[s] = 0;q.push(s); while(!q.empty()) { int u = q.front();q.pop(); for(int i = head[u] ; i != -1;i = edge[i].next) { int v = edge[i].to; if(dis[v] == -1 && edge[i].flow > 0) { dis[v] = dis[u] + 1; if(v == t) return true; q.push(v); } } } return false; } int dfs(int u,int flow_in) { if(u == t) return flow_in; int flow_out = 0; for(int i = cur[u] ; i != -1 ; i = edge[i].next) { cur[u] = i; int v = edge[i].to; if(dis[v] == dis[u] + 1 && edge[i].flow > 0) { int flow = dfs(v,min(flow_in,edge[i].flow)); if(flow == 0) continue; flow_in -= flow; flow_out += flow; edge[i].flow -= flow; edge[i^1].flow += flow; if(flow_in == 0) break; } } return flow_out; } int Dinic(int ans) { int sum = 0; while(bfs()) { for(int i = 0; i <= ans ;i ++) cur[i] = head[i]; sum += dfs(s,inf); } return sum; } int main() { #ifdef LOCAL //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif int T; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); init(); for (int i = 1, u, v, low, up; i <= m; i++) { scanf("%d%d%d%d", &u, &v, &low, &up); in[i] = low; //The initial flow rate of the water, the lower bound ; Low = - A [U] // outflows from the point A [V] + = Low; // inflow this point the Add (U, V, UP- Low); the Add ( V, U, 0 ); // residue network ID [I] = tot- . 1 ; } int S_OUT = 0 ; // record the outflow s for ( int I = . 1 ; I <= n-; I ++ ) { IF (A [I]> 0 ) the Add (S, I, A [I]), the Add (I, S, 0 ), + = S_OUTA [I]; the else IF (A [I] < 0 ) the Add (I, T, -a [I]), the Add (T, I, 0 ); } int max_flow = Dinic (n-+ . 1 ); IF (max_flow == S_OUT) { the printf ( " YES \ n- " ); for ( int I = . 1 ; I <= m; I ++ ) the printf ( " % D \ n- " , in [I] + Edge [ID [I] ] .flow); // add flanging capacity, i.e. the lower bound of the point with respect to increased flow } else { printf("NO\n"); } } return 0; }