Context: Find the maximum flow through a directed graph from s to t. Capacities are all integers.
If I'm not mistaken, Edmonds-Karp runs in O(VE²); and if we don't use a BFS but a DFS instead, it runs in O(E*f) where f is the maximum flow (https://en.wikipedia.org/wiki/Maximum_flow_problem) (proofs: https://enos.itcollege.ee/~japoia/algorithms/GT/Introduction_to_algorithms-3rd%20Edition.pdf chapter 26).
I was a bit surprised that Edmonds-Karp wouldn't pass (but I guess it makes sense looking at the constraints) on a cses problem ( https://cses.fi/problemset/task/1694 ). What really surprised me is that the O(E*f) solution passed (https://cses.fi/paste/aba73738dacf15c9ac0337/ even though the capacities can go up to 10^9 so the max flow can definitely go up to 10^9). I'm now trying to hack my own DFS solution, so I tried to hardcore brute force it by generating billions of inputs and seeing if my DFS would time out on one of them: https://pastebin.com/ijUZDn3G. But that ran so fast (within a minute..) without finding any bad cases...
The worst-case example on wikipedia for that O(E*f) (https://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm) doesn't work for a fixed adjacency list. It just shows that if a bad actor could choose what order DFS goes through the graph, then the algorithm could become crazily slow.
I heard there is this test case generator to hack those O(E*f) solutions but I'll be honest, I don't speak Japanese and I'm not advanced enough to figure out what's happening: https://web.archive.org/web/20211009144446/https://min-25.hatenablog.com/entry/2018/03/19/235802
TL;DR: this code passes https://cses.fi/paste/aba73738dacf15c9ac0337/ even though it's O(E*f) and the capacities can go up to 10^9; please hack me.
(EDIT: my comment in the code saying "DFS to find shortest s-t path" is wrong, it's a remnant comment from when I was coding BFS)
Here is a graph where augmenting paths with DFS requires exponential running time:
Source: "Finite termination of "augmenting path" algorithms in the presence of irrational problem data" by Brian C. Dean, Michel X. Goemans and Nicole Immorlica. https://doi.org/10.1007/11841036_26
This graph is actually test 20 of the CSES problem. There are two reasons why it doesn't work on your algorithm:
The graph is very sensitive to the order of the vertices in the adjacency lists. Test 20 only works, if all edges (and reverse edges!!!) are added into the adjacency lists in the order of the input. You add the reverse edges later in lines 41 and 42. This messes up the intended order.
Your algorithm isn't a DFS. When you search through the neighbours of vertex u and find a new vertex v you continue looking for other neighbours of vertex u. However a DFS would immediately stop searching for neighbours of u and instead look for neighbours of v.
If you add 3 lines to "fix" these things: https://cses.fi/paste/a31c0c721baec2b1ac0707/, then you actually get time limit exceeded on test 20.
Of course it is stupid to change your algorithm so that it performs worse. But the above graph can be slightly modified such that your implementation also has an exponential running time. The following code generates an instance where your code needed more than 2 minutes on my PC to solve it.
Thank you so much. Small question, you say my algorithm isn't a DFS (because I add every neighbour to the stack and then and only then I pop). Isn't that the only way to write an iterative DFS? Can we really write an iterative DFS that doesn't iterate through all neighbours before popping from the stack? EDIT i’m stupid you had changed/fixed it your example, thanks for taking the time!!
Can you already hack my SPFA algorithm please? :D
https://codeforces.me/blog/entry/124509?#comment-1106057