**Link:**Http://acm.zju.edu.cn/onlinejudge/showProblem.do? Problemid = 1314

**Question:**A terrorist organization wants to build a nuclear reactor. They need to design a cooling system, and N points are connected by M tubes. To make the liquid flow cyclically, the total inflow volume of each node must be equal to the total outflow volume, we will tell you the minimum and maximum traffic of each pipe and the two points (directed) connecting them, and ask if there is a feasible flow. If so, we will output the traffic of each pipe.

There are four types of network flows with upper and lower bounds: upstream and downstream feasible flows with no source sink, upstream and downstream feasible flows with source sink, maximum upstream and downstream flows with source sink, and minimum upstream and downstream flows with source sink, this is the first one.

This question is a bare question, and the method for creating such questions is directly described.

**Graph creation:**This type of question graph is usually the companion network of the source image. Based on the companion network, find whether there is a feasible stream and then find the traffic of each arc. When the network is established like this, the super source point vs and super sink point VT are added, and then the d (u) value is obtained for each vertex u, that is, the lower bound of all edges that flow into vertex u and the lower bound sum of all edges of the outbound vertex u. For each vertex u, if d (u) is greater than 0, add an arc from V to u with a capacity of d (u). If d (u) is <0, add an arc from u to VT with a capacity of-d (u, d (u) = 0 is not added, and d (u) can be reduced in turn. There is also a method of subtraction on the Internet, but it must be reversed when the edge is connected, that is, d (u)> 0 is connected to VT, d (u) <0 is connected from. For the arc in the source image, it must also be established in the companion network, except that the arc capacity changes to the upper and lower bounds, that is, an arc without the minimum flow limit.

I don't post any proof methods. I have a lot of ideas online.

**Dinic code**And paste the ISAP code when I have mastered the ISAP template.

#include<cstring>#include<string>#include<fstream>#include<iostream>#include<iomanip>#include<cstdio>#include<cctype>#include<algorithm>#include<queue>#include<map>#include<set>#include<vector>#include<stack>#include<ctime>#include<cstdlib>#include<functional>#include<cmath>using namespace std;#define PI acos(-1.0)#define MAXN 500100#define eps 1e-7#define INF 0x7FFFFFFF#define LLINF 0x7FFFFFFFFFFFFFFF#define seed 131#define mod 1000000007#define ll long long#define ull unsigned ll#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1struct node{ int u,w,next; int ww;}edge[MAXN];int head[220],dist[220];int n,cnt,m,src,sink;int low[50100],D[50100];void add_edge(int a,int b,int c){ edge[cnt].u = b; edge[cnt].w = c; edge[cnt].next = head[a]; head[a] = cnt++;}bool bfs(){ int i,j; memset(dist,-1,sizeof(dist)); dist[src] = 1; queue<int>q; q.push(src); while(!q.empty()){ int u = q.front(); q.pop(); for(i=head[u];i!=-1;i=edge[i].next){ int v = edge[i].u; if(dist[v]==-1&&edge[i].w){ dist[v] = dist[u] + 1; q.push(v); } } } if(dist[sink]!=-1) return true; return false;}int dfs(int u,int delta){ int i,j,dd; if(u==sink||delta==0) return delta; int ret = 0; for(i=head[u];i!=-1;i=edge[i].next){ int v = edge[i].u; if(dist[v]==dist[u]+1&&edge[i].w){ dd = dfs(v,min(delta,edge[i].w)); edge[i].w -= dd; edge[i^1].w += dd; delta -= dd; ret += dd; } } return ret;}int main(){ int i,j,t; int a,b,c,d; scanf("%d",&t); while(t--){ memset(head,-1,sizeof(head)); memset(D,0,sizeof(D)); scanf("%d%d",&n,&m); cnt = 0; src = 0; sink = n + 1; for(i=0;i<m;i++){ scanf("%d%d%d%d",&a,&b,&low[i],&d); D[b] += low[i]; D[a] -= low[i]; add_edge(a,b,d-low[i]); add_edge(b,a,0); } for(i=1;i<=n;i++){ if(D[i]==0) continue; if(D[i]>0){ add_edge(src,i,D[i]); add_edge(i,src,0); } else{ add_edge(i,sink,-D[i]); add_edge(sink,i,0); } } int ans = 0; while(bfs()){ ans += dfs(src,INF); } //cout<<ans<<endl; int flag = 0; for(i=head[src];i!=-1;i=edge[i].next){ if(edge[i].w!=0){ flag = 1; break; } } if(!flag){ for(i=head[sink];i!=-1;i=edge[i].next){ if(edge[i^1].w!=0){ flag = 1; break; } } } if(flag) puts("NO"); else{ puts("YES"); for(i=0;i<m;i++){ printf("%d\n",edge[(i*2)^1].w+low[i]); } } puts(""); } return 0;}