Variant of bipartite matching, with real capacities from source and to sink, all others unlimited
Looks like the answer I was looking for was something like Dinitz's algorithm with dynamic trees. There are some implementation optimizations that can be added since we know it's a bipartite graph.