Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Flow & Matching  ›  Capstone Project

Capstone: Meridian's Dispatcher

45 minRun max flow, find the limiting cut in the final residual graph, and price the cheapest pipe worth widening — the whole section in one report
You're building a piece ofMeridian — the dispatcher
This piece — dispatch_plan(): Runs the whole roster: how much ships, which pipes are the limiting cut, and which is cheapest to widen.
Scenario End of shift: how much actually moved, which pipes are the reason it wasn't more, and if there's budget for exactly one upgrade before tomorrow, which pipe buys the most.
Your task
Build dispatch_plan(routes, source, sink). routes is [from, to, capacity, widen_cost]. Run max flow to get "dispatched". Find the nodes still reachable from source in the final residual graph; the pipes leaving that set are "cut_edges" and their capacities sum to "cut_capacity". Among the cut edges, report the smallest widen_cost as "cheapest_widen" (None if there are no cut edges). Example: dispatch_plan([["s", "a", 3, 2], ["a", "t", 2, 5]], "s", "t") -> {"dispatched": 2, "cut_edges": [["a", "t"]], "cut_capacity": 2, "cheapest_widen": 5}.

Capstone: Meridian's Dispatcher

In short: This section built four pieces — how much a network can carry, exactly which pipes are the reason it isn't more, a faster way to find the first number, and the cheapest way to move a fixed amount. The dispatcher puts the first two together into one end-of-shift report: run max flow, read the limiting cut straight out of the leftover residual graph, and price the cheapest pipe on that cut worth widening before tomorrow's shift. Nothing here is a new algorithm. It's the same residual graph, asked three questions instead of one.

Meridian's fixed shift roster

Two feeder docks, a shared hub, and a quieter side route through berth — four departures, two of them already pinched:

watch it move · graph

Widen costs, not shown here, ride along on each pipe for later. The run below only needs capacity.

Meridian's roster: two docks feed a shared hub, and dockB also has a quieter side route through berth. 6 nodes, 7 edges, directed. At depot.

1 / 6

Pulling the section together

python

Quick practice: reading the report

dispatched: 6 is the number ops cares about first thing in the morning. cut_edges and cut_capacity are the number finance needs before they'll approve anything: not "the network is slow," but "these two specific pipes are the entire reason it's 6 and not more." cheapest_widen turns that into a decision — of the two pipes actually worth touching, dockB-berth at 4 beats hub-harbour at 6, so that's where the next rupee goes, and lesson 2's widen_helps is the proof that spending it anywhere else (depot-dockA, say) buys nothing at all.

What does this print?
# roster's cut: hub-harbour costs 6 to widen, dockB-berth costs 4
cut_widen_costs = [6, 4]
print(min(cut_widen_costs))

What the whole section bought Meridian

Lesson Question Answer for the roster
1. Maximum Flow How much, total? 6
2. Min Cut & Duality Which pipes, exactly? dockB-berth, hub-harbour
3. Faster Flow How fast can I ask again? Same answer, fewer BFS rounds
4. Min-Cost Flow What's the cheapest way to move less than the max? Fill the cheap routes first
5. Capstone Put it together, then spend wisely cheapest_widen: 4

❓ Cross-question: "If I widen dockB-berth by 1, does the max flow actually go up, or could the OTHER cut edge still cap it?" It goes up. Lesson 2 proved every cut edge is independently a bottleneck — widening one that's actually on the cut always raises the max flow by exactly 1, because the cut's capacity (the thing the max flow equals) went up by 1.


🎯 Your turn

Write dispatch_plan(routes, source, sink). routes is [from, to, capacity, widen_cost]. Run max flow, find the cut in the final residual graph, and report the cheapest cut edge to widen:

  • dispatch_plan([["s", "a", 3, 2], ["a", "t", 2, 5]], "s", "t") → {"dispatched": 2, "cut_edges": [["a", "t"]], "cut_capacity": 2, "cheapest_widen": 5}

Hint: this is lessons 1 and 2, run back to back, with a {(from, to): widen_cost} lookup built once at the start.

Then press ▶ Run, tap the Live App try chips to call it with different inputs, and hit ✓ Check. Green = Meridian's dispatcher is fully built. ✅

Practice — level up

0/5 solved

Solve each in its own editor — Run to try, Check to grade. Stuck? Reveal a Hint, or the full Solution + walkthrough.

Warm-upHow much can leave this depot

Write total_capacity_leaving(routes, node) where routes is [from, to, capacity, widen_cost]. Return the total capacity of every route leaving node. Example: total_capacity_leaving([["s", "a", 3, 1], ["s", "b", 2, 1]], "s") -> 5.

network-flowmax-flow
DrillDoes this route cross the line

Write is_crossing(routes, u, v, source_side) returning True if a route from u to v exists in routes AND u is in source_side while v is not. Example: is_crossing([["hub", "harbour", 4, 6]], "hub", "harbour", ["depot", "hub"]) -> True.

min-cutnetwork-flow
BuildSummarise a given cut

Write cut_summary(routes, source_side) returning {"edges": sorted [from, to] pairs crossing out of source_side, "capacity": their capacity sum, "cheapest_widen": the smallest widen_cost among them, or None if there are no crossing routes}. Example: cut_summary([["s", "a", 3, 2], ["s", "b", 2, 1]], ["s"]) -> {"edges": [["s", "a"], ["s", "b"]], "capacity": 5, "cheapest_widen": 1}.

min-cutnetwork-flow
BossHow much ships, ignoring price

Write roster_max_flow(routes, source, sink) returning just the max flow (an int) through a routes network — same shape as lesson 1's push_volume, but routes carries a widen_cost on each entry that this function ignores entirely. Example: roster_max_flow([["s", "a", 3, 2], ["a", "t", 2, 5]], "s", "t") -> 2.

max-flowedmonds-karpnetwork-flow
CapstoneWhere should the next rupee of maintenance budget go

Write best_widen_within_budget(routes, source, sink, budget) returning the [from, to] cut edge with the SMALLEST widen_cost that is also <= budget, or None if no cut edge is affordable (including when there's no cut at all). Widening any cut edge by 1 unit raises the max flow by exactly 1, so the cheapest affordable one is always the best choice. Example: best_widen_within_budget([["s", "a", 3, 2], ["a", "t", 2, 5]], "s", "t", 10) -> ["a", "t"].

min-cutmax-flownetwork-flow
dispatch_plan.py
Call the function you wrote — just like your app's frontend would. Edit the inputs and hit Call.
dispatch_plan(routes, source, sink) → dictThe full shift report: how much ships, which pipes are the limiting cut, and which is cheapest to widen.
try:
returned
Press Run to execute your code.
Press Check to run the tests for this lesson.