-
Notifications
You must be signed in to change notification settings - Fork 775
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
Improve MCMF #237
Conversation
There was a problem hiding this 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
@@ -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) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
kactl/content/graph/MinCostMaxFlow.h
Lines 53 to 56 in 48ca736
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.
kactl/content/graph/MinCostMaxFlow.h
Lines 67 to 74 in 48ca736
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; | |
} |
Co-authored-by: Simon Lindholm <[email protected]>
7868c30
into
kth-competitive-programming:main
This PR improves 3 things:
Empirically, it also seems to improve performance (see "improved MCMF" here)
Potential downsides of new implementation:
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?