Catalog
In the solution of Luogu problem, we can see a very enlightening remark: network flow is good at solving all kinds of required matching.
Considering that the topic is matching and the data range that meets the requirements of network flow, you can try network flow.
V is the number of points and E is the number of edges.
Maximum flow algorithm
(EK algorithm)
Time complexity O(V*(E^2))
Definition:
We have a source (only outflow) and a sink (only inflow).
Each side has a flow and capacity, the flow is initially 0, the capacity is the title tells us, we require the flow of all sides <= capacity & & each point inflow = outflow, the maximum flow into the confluence.
First of all, we need to know about residual networks:
Residual network is the flow of reverse graph. We are going to traverse a graph and take a path to the confluence point.
The augmented path of a path = min (the {capacity-current traffic} of each side passing through)
But our side may be a reverse flow, so
- Capacity of forward edge - = augmented path
- Reverse Side Capacity + = Augmented Path
Find an augmented road, we will flow + = augmented Road
When no augmented path is found, the algorithm is terminated.
Because of the efficiency and space difference between vector mapping and chain forward star mapping, we changed the template manually, instead of using the commonly used mp [][] array tags, we practiced the chain forward star.
Luogu 3376
#include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <iostream> #include <cmath> #include <map> #include <queue> #include <algorithm> #include <set> #include <vector> #include <stack> #define Clear( x , y ) memset( x , y , sizeof(x) ); #define Qcin() std::ios::sync_with_stdio(false); using namespace std; typedef long long LL; const int Maxn = 1e4 + 7; const int MaxN = 2e5 + 7; const int Inf = 1e9 + 7; // O{V * E ^ 2} /* Source st, sink ed */ int N , M; int st , ed; int cnt; struct edge{ int Next;//Storage subscripts for the next side int to;//The end of this side int w;//Border rights }; edge Edge[MaxN]; int head[Maxn];//Marking of the first edge starting with i void AddEdge(int u , int v , int w){ Edge[++cnt].Next = head[u]; Edge[cnt].w = w; Edge[cnt].to = v; head[u] = cnt; } int pre[Maxn][2]; int Flow; int flow[Maxn]; queue <int> que; bool Bfs(){ while(!que.empty()) que.pop(); for(int i = 0 ; i <= N ; i++) pre[i][0] = pre[i][1] = -1; flow[st] = Inf; int q; que.push(st); while(!que.empty()){ q = que.front(); que.pop(); if(q == ed) break; for(int i = head[q] ; ~i ; i = Edge[i].Next){ int nq = Edge[i].to; if(nq != st && Edge[i].w && pre[nq][0] == -1){//The next point nq is not st, and the edge weight is > 0. nq has not been traversed. pre[nq][0] = i;//Record the number of the previous side pre[nq][1] = q;//Record the point q before nq flow[nq] = min(Edge[i].w , flow[q]);//Take min edge weight on nq path que.push(nq); } } } if(pre[ed][0] == -1) return false; return true; } void MaxFlow(){ int add , pl , fa , p; while(Bfs()){ add = flow[ed]; p = ed; while(p != st){ pl = pre[p][0];//Number of the edge on p p = pre[p][1];//p becomes its last point Edge[pl].w -= add; Edge[pl^1].w += add; } Flow += add; } printf("%d\n",Flow); return; } void init(){ for(int i = 0 ; i <= N ; i++) head[i] = -1; cnt = -1;//Starting with -1, you can use x ^ 1 to correlate positive and negative sides return; } int main() { scanf(" %d %d %d %d",&N,&M,&st,&ed); init(); for(int i = 1 ; i <= M ; i++){ int u , v , c , ct1 , ct2; scanf(" %d %d %d",&u,&v,&c); AddEdge(u , v , c); AddEdge(v , u , 0); } MaxFlow(); return 0; }
Dinic algorithm
EK usually solves 10 ^ 3 - 10 ^ 4 scale networks.
dinic can solve 10 ^ 4 - 10 ^ 5 Network
Time complexity O((V ^ 2)* E)
(It's really fast, not a bit. Dinic is a quarter of EK's time.)
Algorithmic flow:
- If the convergence point is not on the hierarchical graph with augmented paths, there will be no new augmented paths and the end algorithm.
- When there are confluence augmented paths, Dfs operation is performed to find augmented paths from u to V in the hierarchical graph, if and only if dep[v] = dep[u] + 1
- If an augmented path is found, the augmented path may be subtracted from the Dfs backtracking, and a node may reduce the augmented path several times.
Luogu 3376
#include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <iostream> #include <cmath> #include <map> #include <queue> #include <algorithm> #include <set> #include <vector> #include <stack> #define Clear( x , y ) memset( x , y , sizeof(x) ); #define Qcin() std::ios::sync_with_stdio(false); using namespace std; typedef long long LL; const int Maxn = 1e4 + 7; const int MaxN = 2e5 + 7; const int Inf = 1e9 + 7; int N , M; int st , ed; int Flow; int cnt; struct edge{ int Next; int to; int w; }; edge Edge[MaxN]; int head[Maxn]; void AddEdge(int u , int v , int w){ Edge[++cnt].Next = head[u]; Edge[cnt].w = w; Edge[cnt].to = v; head[u] = cnt; } int dep[Maxn]; queue <int> que; bool Bfs(){ for(int i = 1 ; i <= N ; ++i) dep[i] = 0; while(!que.empty()) que.pop(); dep[st] = 1; que.push(st); int q , v; while(!que.empty()){ q = que.front(); que.pop(); for(int i = head[q] ; ~i ; i = Edge[i].Next){ v = Edge[i].to; if(Edge[i].w && !dep[v]){ que.push(v); dep[v] = dep[q] + 1; if(v == ed) return true; } } } return false; } int Dfs(int x , int flow){ if(x == ed) return flow; int res = flow , add; for(int i = head[x] ; ~i && res ; i = Edge[i].Next){ int v = Edge[i].to; if(Edge[i].w && dep[v] == dep[x] + 1){ add = Dfs(v , min(res , Edge[i].w)); if(!add) dep[v] = 0; Edge[i].w -= add; Edge[i^1].w += add; res -= add; } } return flow - res; } void Dinic(){ int flow; while(Bfs()){ while(flow = Dfs(st , Inf)){ Flow += flow; } } printf("%d\n",Flow); } void init(){ for(int i = 1 ; i <= N ; i++) head[i] = -1; Flow = 0; cnt = -1; } int main() { scanf(" %d %d %d %d",&N,&M,&st,&ed); init(); for(int i = 1 ; i <= M ; i++){ int u , v , c; scanf(" %d %d %d",&u,&v,&c); AddEdge(u , v , c); AddEdge(v , u , 0); } Dinic(); }
Luogu P2763
We have learned the basic maximum flow, so we need to continue to study the minimum cost maximum flow and the maximum cost maximum flow.
Minimum Cost Maximum Flow