Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve MCMF #237

Merged
merged 13 commits into from
Jan 14, 2024
Merged

Improve MCMF #237

merged 13 commits into from
Jan 14, 2024

Conversation

Matistjati
Copy link
Contributor

@Matistjati Matistjati commented Dec 23, 2023

This PR improves 3 things:

  1. Fixes the time complexity description, as mentioned in Wrong Time Complexity for MinCostMaxFlow #217
  2. No longer uses quadratic memory (adjacency list instead of matrix). Quadratic memory was problematic on problems with sparse graphs such as tourist.
  3. Allows parallell/double edges.

Empirically, it also seems to improve performance (see "improved MCMF" here)

Potential downsides of new implementation:

  1. Loops (edges from a node to itself) don't work (when would you ever want that, though?)
  2. Uses pointers to easily reconstruct path, making some parts less readable.

It passes all stress tests and doesn't get any WA's on the kattis problems I've tried. It might be worth to consider using SPFA for setpi if it does not complicate the code too much.

Side note: does anyone know why we can skip using setpi if input costs are positive?

Copy link
Member

@simonlindholm simonlindholm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice to hear this improves perf, I was worried about that before but I guess it makes sense. (Maybe it would another thing if the vector<vector<>> was a packed matrix.)

I agree self loops aren't interesting -- they could be if they had negative weight but we don't handle negative weight cycles anyway. And them not showing up in the list of edges doesn't feel like a problem at all since you'll be filtering out the subset of edges with flow > 0 anyway if you ever go through it.

content/graph/MinCostMaxFlow.h Outdated Show resolved Hide resolved
content/graph/MinCostMaxFlow.h Outdated Show resolved Hide resolved
content/graph/MinCostMaxFlow.h Outdated Show resolved Hide resolved
@@ -68,15 +63,17 @@ struct MCMF {
ll totflow = 0, totcost = 0;
while (path(s), seen[t]) {
ll fl = INF;
for (int p,r,x = t; tie(p,r) = par[x], x != s; x = p)
fl = min(fl, r ? cap[p][x] - flow[p][x] : flow[x][p]);
for (int p, x = t; par[x] && (p = par[x]->from, x != s); x = p)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you make fast to create kactl.pdf you see this line overflowing from having > 63 chars; any way it could be shortened to keep it on a single line? E.g. shorten par or from or trim some whitespace or move the declaration of p out. Or actually, remove p since it doesn't seem to be used other than in one place? There are some other lines that just barely overflow too.

Copy link
Contributor Author

@Matistjati Matistjati Jan 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I chose to use python-style ifs to fix the "push into priority queue" from overflowing. A bit stylistically inconsistent, but probably fine?

if (its[e.to] == q.end())
its[e.to] = q.push({ -dist[e.to], e.to });
else
q.modify(its[e.to], { -dist[e.to], e.to });

After fiddling with the loops, I found a pretty clean solution in the end. All overflows should be fixed now.

for (edge* x = par[t]; x; x = par[x->from])
fl = min(fl, x->cap - x->flow);
totflow += fl;
for (edge* x = par[t]; x; x = par[x->from]) {
x->flow += fl;
ed[x->to][x->rev].flow -= fl;
}

content/graph/MinCostMaxFlow.h Outdated Show resolved Hide resolved
content/graph/MinCostMaxFlow.h Outdated Show resolved Hide resolved
content/graph/MinCostMaxFlow.h Outdated Show resolved Hide resolved
content/graph/MinCostMaxFlow.h Outdated Show resolved Hide resolved
@simonlindholm simonlindholm merged commit 7868c30 into kth-competitive-programming:main Jan 14, 2024
1 check passed
kuroni pushed a commit to kuroni/purdue-btr that referenced this pull request Jan 18, 2024
hockyy pushed a commit to hockyy/kactl that referenced this pull request Mar 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants