← Все вопросы

Как задать пропускную способность на вершине (vertex capacity) в задаче о потоке?

Задан 9 месяцев назад879 просмотров2 ответа
9

В задаче ограничение не на рёбра, а на вершины: через вершину vv может пройти не более capvcap_v единиц потока. Классический max-flow умеет только рёберные ограничения. Как свести вершинные пропускные к обычной задаче о потоке?

2 ответа

15
✓ Принятый ответ — помог автору

Приём «расщепление вершины» (vertex splitting). Каждую вершину vv с пропускной способностью capvcap_v заменяем на две: vinv_{in} и voutv_{out}, соединённые ребром vinvoutv_{in} \to v_{out} с пропускной способностью capvcap_v.

Правило перенаправления рёбер:

  • все рёбра, входившие в vv, теперь входят в vinv_{in};
  • все рёбра, выходившие из vv, теперь выходят из voutv_{out}.

Теперь весь поток, проходящий через vv, обязан пройти по «внутреннему» ребру vinvoutv_{in}\to v_{out}, и его пропускная способность capvcap_v ограничивает поток через вершину. Дальше — обычный max-flow.

// нумерация: vin(v) = 2*v, vout(v) = 2*v+1
for(int v=0; v<V; v++) add_edge(2*v, 2*v+1, capVertex[v]); // ребро вершины
for(auto&[u,w,c]:origEdges) add_edge(2*u+1, 2*w, c);       // u_out -> w_in
int flow = maxflow(2*s+1, 2*t); // источник — это s_out, сток — t_in

Размер сети удваивается по вершинам (2V2V) и добавляется VV рёбер — это O(V)O(V) накладных расходов, асимптотика алгоритма не меняется. Этот приём — основа множества задач: «максимум вершинно-непересекающихся путей» (теорема Менгера), задачи с лимитами на узлы сети и т.п.

5

Внимание к истоку и стоку при расщеплении: для них тоже создаются inin/outout, но запускать поток надо из souts_{out} в tint_{in} (как в коде выше), иначе вы случайно ограничите сам исток/сток. Если у ss и tt нет своего лимита, можно либо ставить им cap=cap=\infty на внутреннем ребре, либо вообще не расщеплять их и брать ss как souts_{out}, tt как tint_{in} напрямую. Главное — быть последовательным в нумерации, иначе тихо получите неверный ответ.

Ваш ответ

Войдите, чтобы ответить на вопрос.