У меня есть небольшая ошибка в понимании алгоритма Диника о том, как он использует остаточную сеть.
так что алгоритм, насколько я понимаю, следующий
1- запустить bfs в остаточной сети и назначить уровни узлам в зависимости от расстояния от источника
2- если узел приемника так и не был достигнут, завершить алгоритм
3- запустить итерации dfs, идущие со строго возрастающими уровнями, чтобы найти пути увеличения, пока не будет достигнут блокирующий поток, и просуммировать все значения узких мест путей увеличения, чтобы получить максимальный поток и обновить остаточную сеть в соответствии с узким местом каждого пути.
4- повторить 1 2 3
теперь мой вопрос: использует ли этот алгоритм когда-либо обратные края остаточной сети (те, которые идут от v к u вместо u к v, чтобы отменить существующий поток сети) во время итераций dfs?
потому что я обычно представляю остаточные ребра таким образом: -
private static class ResidualEdge implements Comparable<ResidualEdge>{
public int u, v;
public long flow;
public boolean reversed;
public Edge originEdge;
public ResidualEdge(int u, int v, long flow, boolean reversed, Edge originEdge) {
this.u = u;
this.v = v;
this.flow = flow;
this.reversed = reversed;
this.originEdge = originEdge;
}
@Override
public boolean equals(Object obj) {
if(obj == null || !(obj instanceof ResidualEdge))
return false;
ResidualEdge edge = (ResidualEdge)obj;
return edge.u == u && edge.v == v && edge.flow == flow && this.originEdge == edge.originEdge && this.reversed == edge.reversed;
}
@Override
public int hashCode() {
return Integer.hashCode((int) (flow + u + v + Boolean.hashCode(reversed)));
}
@Override
public int compareTo(ResidualEdge o) {
if(flow > o.flow)
return 1;
else if (flow < o.flow)
return -1;
return 0;
}
}
originEdge является ссылкой на исходный край исходной сети, а остаточный край представляет собой оставшуюся емкость или поток, который необходимо отменить, чтобы упростить обновление исходной сети.
теперь я спрашиваю об этом, потому что, если алгоритм Диника не использует перевернутые края, я могу просто игнорировать представление перевернутых ребер, и алгоритм будет намного проще