Summer had already learned, but because I was too dishes, so completely did not understand, learned today before the teacher wants us to implement, will review the network flow
Although CSP not test, but the school can also be used (like last year D2T3, DP dynamic template)
Well, then get to the point:
First of all, what wisdom network flow, the official explained below
In graph theory, network flow (in English: Network flow) means that each edge has a capacity (capacity) are assigned to the flow chart, the flow rate of an edge does not exceed its capacity.
Typically in operations research, it has referred to the network of FIG. Vertices called nodes (node) and the called side arc (arc). A flow restricting flow must match the same out of a node, unless this is a source node (source) ── have more outward flow,
or a sink (sink) ── have more inwardly flow. Network can be used to simulate a road traffic system, in the liquid pipe, anything current in the circuit or something similar at the network node in a swimming.
Hey, it seems to understand, simpler terms:
There is a storage station, distribution of water to a community, and you live there
Each household has different specifications of the water, how many different words, in the case of the same speed, the same time, the flow of water
And sent out from the inside of the water storage station must be the same speed, because the faster the velocity the greater the pressure of liquid
We certainly do not want to burst water pipe
Each family will certainly have to run out of water transported to a waste water treatment station
We request that the storage station how much water can be sent up to the last can be sent to a wastewater treatment plant (due to the recycling)
The first time I saw this topic, resulting in a conversation:
Me: Is not this violent enumerate it? ? ?
A giant guy: ...... this time out of
me: ...... how to do that
in a huge guy: EK or Dinic
me:? ? ? WTF
First, clear a few concepts:
Capacity: Each side has a capacity (maximum flow capacity of the pipe)
Source: the starting point (water storage station).
Meeting Point: End point (wastewater treatment plant).
Streams: a stream called a legal solution, i.e. be a valid path from a source to a sink.
Flow rate: the number of times each through each side of its flow is referred to, the total number of the flow eventually collected for the entire stream.
Augmenting path: to find a path to be able to be able to transport more goods from source to sink behind the current network. When an edge is augmented (i.e., it is part of augmenting paths, or augmenting path through this edge), this edge can flow through, it is called the remaining traffic, then the modification of FIG residual network is called .
The first is my favorite EK algorithm (mainly the code easy to understand, simple, for me this Tacca)
Its idea is simple, every crazy looking augmenting path, of course, if there was an edge to '0', it is not augmenting path, the current flow rate minus the minimum middle (yes, because if not the smallest of the water will not pass)
ans plus the current minimum, until looking less than augmenting path
However flawed, you can put this hack out:
We can easily know that the answer is 2, but if you follow the above ideas:
The program will run so that ans = 1:
So, we need to give this program a chance to regret
Is not thought dfs back, obviously, overtime
So we thought of a clever way to build the anti-side, the initial value is zero
Looking for augmenting paths when the minimum flow set this path is opt
So, the anti-edge value + opt, positive side -opt
We may think that we are going in the opposite side of the water is equivalent to pull back
Okay, so, AC code is as follows:
#include<bits/stdc++.h> using namespace std; const int N=300002; int spot,EDGE,S,E; int head[N],ver[N],nxt[N],tot,edge[N]; int q[N],hd,tl,res[N],now[N],pre[N],ans; int read(){ int s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9')w=(ch=='-')?-1:1,ch=getchar(); while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar(); return s*w; } void write(int x){ if(x<0) {putchar('-');x=-x;} int y=10,len=1; while(y<=x) {y*=10;len++;} while(len--){y/=10;putchar(x/y+48);x%=y;} } void add(int x,int y,int z){ ver[++tot]=y;edge[tot]=z;nxt[tot]=head[x];head[x]=tot; } bool Bfs(){ memset(res,0,sizeof(res)); hd=0;tl=1;q[1]=S;res[S]=1;now[S]=1e9; while(hd^tl){ hd++; int x=q[hd]; for(int i=head[x];i;i=nxt[i]){ int y=ver[i]; if(!res[y]&&edge[i]>0){ now[y]=min(now[x],edge[i]);pre[y]=i; if(y==E)return 1; tl++;q[tl]=y;res[y]=1; } } } return 0; } void EK(){ ans+=now[E]; int x=E; while(x!=S){ edge[pre[x]]-=now[E];edge[pre[x]+1]+=now[E]; x=ver[pre[x]+1]; } } int main(){ EDGE=read();S=1;E=read(); for(int i=1;i<=EDGE;i++){ int x=read(),y=read(),z=read(); add(x,y,z);add(y,x,0); } while(Bfs())EK(); write(ans); return 0; }
// 10-2 //