Please, try EDU on Codeforces! New educational section with videos, subtitles, texts, and problems. ×

[Help] Push Relabel Algorithm Tutorial

Revision en2, by RNR, 2019-07-19 16:07:03

I have studied the Push-Relabel algorithm, the main difference between Augmenting path algorithms and Push-Relabel is that:

  • Augmenting path algorithms maintain a flow(capacity constraints and conservation constraints are valid) and augment it some s-t path in each iteration to increase its value. We iterate untill there exists no s-t path in the current residual network.
  • Push-Relabel algorithm takes a different approach, it works with pre-flow(conservation constraint is violated — the amount of flow into a vertex can exceed the amount of flow exiting it, the amount present at that vertex is called excess, excess > 0). This algorithm starts with a pre flow and terminates with an actual flow, eliminates all the excesses. We start with s-t disconnected and work towards a feasible flow.

To eliminate excess at a vertex it has the following function:

    choose an outgoing edge (v, w) of v in Residual graph G_f (if any)
    // push as much flow as possible
    let fl = min{excess(v), capacilty of edge(v, w)}
    push fl units of flow along (v, w)

Choose an edge(what type of edge will be clear later) and push as much as we can.

We maintain heights to route flow from source to sink, otherwise, if we have a cycle in the network we might end up pushing around it indefinitely. To route the excess flow systematically we maintain these heights, heights are always non-negative, and thus we can visualize edges going uphill, downhill or at the same level. We maintain these invariants, let's denote height by h then h(src)=|V|, h(sink)=0 and for every edge (v, w) of the current residual network G_f (with positive residual capacity), h(v) <= h(w) + 1, the third one says that if we have to go downhill through the edges we only go down 1 step at a time(height doesn't go down quickly).

The motivation for invariants: We maintain that s-t is disconnected as h(s)=|V| and h(t)=0 if there is a path then it is of length atmost |V|-1.

We initialize the network with the following:

h(s) = |V|
h(v) = 0 for V-{s}
flow = capacity for (s,*) // edges going out of source 
flow = 0 for E-{(s,*)}

The Pre-flow for edges going out of s is at full capacity so as to maintain the third invariant so that we don't have edges going out of s with positive residual capacity.

We restrict the above Push() operation — flow is only allowed to be pushed downhill in the residual network. This restriction allows us to maintain invariants, if we push uphill then we get reverse arcs in the residual network which violate h(v) <= h(w) + 1.

The main iteration in this algorithm is to choose a vertex v in V-{s,t} with excess[v]>0, if there are many such vertices, choose any vertex with maximum height. Now if we have an edge going out of v in G_f with h(v)=h(w)+1, then Push() over this edge (v,w).

While there exists v in V-{s,t} with excess[v]>0:
    Choose any vertex v with a maximum height
    if there is an outgoing edge (v, w) of v in Gf with h(v) = h(w) + 1

The idea behind choosing maximum height is to select one furthest away from the sink t. The hope is that working on those nodes will move the flow towards the sink, and aggregate them along the way.

Here is the Relabel(v) algorithm


One can observe that the same vertex will be relabelled until we find a vertex w such that h(v)=h(w)+1 so we can rewrite the Relabel(v) function as follows:

    for all edges (v,w) with positive residual capacity

About the running time $$$O(n^3)$$$:

  • If the vertex v has positive excess in the pre-flow f, then there is a path v->s in the residual network G_f. — Clearly, the excess must have come from the source only so there should be a path to s.

  • In the push-relabel algorithm, every vertex always has height at most 2|V|. — As the height of source is |V|, and there is a path from v to s and height invariant. Therefore, the push-relabel algorithm performs $$$O(n^2)$$$ relabels

  • Now if we think when the Push will flow will be bounded by Capacity(Saturating pushes) and when it will be bounded by Excess(Non-saturating pushes), One can prove that Between two saturating pushes on the same edge (v, w) in the same direction, each of v, w is relabeled at least twice. and Between any two relabel operations, there are at most n non-saturating pushes.

Here is the implementation:


I just need help in the Main loop with finding a vertex v with ex[v]>0 && max-height in the above code in max_flow() function

        // find a vertex v with ex[v]>0 && max height
        for(int id=0;id<(int)adj[v].size() && ex[v];id++){
            edge e=ed[id];
            if(e.cap-e.f>0 && h[v]==h[]+1){
        if(!pushed) relabel(v);

I have gone through the code in CP-algorithms, is there any better way?

I have gone through Stanford notebook but I didn't understand Gap method in it, what does it do?

Can someone help me in completion of my code(finding the maximum height excess vertex in $$$O(1)$$$) time?

Tags push-relabel, #network flow, flow, flow networks


  Rev. Lang. By When Δ Comment
en5 English RNR 2019-07-20 04:54:10 2299 Tiny change: 'g it, the amoun' -> 'g it, the difference(flow_in-flow_out) in the amoun'
en4 English RNR 2019-07-19 20:35:46 2219 Tiny change: 'n~~~~~\n\n\n</spoi' -> 'n~~~~~\n\n</spoi'
en3 English RNR 2019-07-19 16:32:40 627 Tiny change: 'uristic]\nLet g be' -> 'uristic]\n\nLet g be'
en2 English RNR 2019-07-19 16:07:03 234 Tiny change: 'rtex v in V-{s,t} with exce' -> 'rtex v in $V-{s,t}$ with exce'
en1 English RNR 2019-07-19 15:11:54 6602 Initial revision (published)