/// Returns the amount the flow can be augmented over the paths, 0 if no path can be found. ##TSnap::FindAugV int FindAugV (const PNEANet &Net, const int& CapIndex, TIntV &Flow, TIntQ &FwdNodeQ, TIntH &PredEdgeH, TIntQ &BwdNodeQ, TIntH &SuccEdgeH, TIntV &MidToSrcAugV, TIntV &MidToSnkAugV, const int& SrcNId, const int& SnkNId) { int MidPtNId = IntFlowBiDBFS(Net, CapIndex, Flow, FwdNodeQ, PredEdgeH, BwdNodeQ, SuccEdgeH, SrcNId, SnkNId); if (MidPtNId == -1) { return 0; } int MinAug = TInt::Mx, NId = MidPtNId, AugFlow = 0; // Build the path from the midpoint back to the source by tracing through the PredEdgeH for (int EId = PredEdgeH.GetDat(NId); NId != SrcNId; EId = PredEdgeH.GetDat(NId)) { MidToSrcAugV.Add(EId); const TNEANet::TEdgeI &EI = Net->GetEI(EId); if (EI.GetSrcNId() == NId) { NId = EI.GetDstNId(); AugFlow = Flow[EId]; } else { NId = EI.GetSrcNId(); AugFlow = Net->GetIntAttrIndDatE(EId, CapIndex) - Flow[EId]; } if (AugFlow < MinAug) { MinAug = AugFlow; } } NId = MidPtNId; // Build the path from the midpoint back to the sink by tracing through the SuccEdgeH for (int EId = SuccEdgeH.GetDat(NId); NId != SnkNId; EId = SuccEdgeH.GetDat(NId)) { MidToSnkAugV.Add(EId); const TNEANet::TEdgeI &EI = Net->GetEI(EId); if (EI.GetDstNId() == NId) { NId = EI.GetSrcNId(); AugFlow = Flow[EId]; } else { NId = EI.GetDstNId(); AugFlow = Net->GetIntAttrIndDatE(EId, CapIndex) - Flow[EId]; } if (AugFlow < MinAug) { MinAug = AugFlow; } } return MinAug; }
int GetMaxFlowIntEK (PNEANet &Net, const int &SrcNId, const int &SnkNId) { IAssert(Net->IsNode(SrcNId)); IAssert(Net->IsNode(SnkNId)); if (SrcNId == SnkNId) { return 0; } int CapIndex = Net->GetIntAttrIndE(CapAttrName); TIntV Flow(Net->GetMxEId()); // Initialize flow values to 0, and make sure capacities are nonnegative for (TNEANet::TEdgeI EI = Net->BegEI(); EI != Net->EndEI(); EI++) { IAssert(Net->GetIntAttrIndDatE(EI, CapIndex) >= 0); Flow[EI.GetId()] = 0; } // Return 0 if user attempts to flow from a node to itself. if (SrcNId == SnkNId) { return 0; } int MaxFlow = 0, MinAug, CurNId; while (true) { TIntV MidToSrcAugV; TIntV MidToSnkAugV; TIntQ FwdNodeQ; TIntQ BwdNodeQ; TIntH PredEdgeH; TIntH SuccEdgeH; MinAug = FindAugV(Net, CapIndex, Flow, FwdNodeQ, PredEdgeH, BwdNodeQ, SuccEdgeH, MidToSrcAugV, MidToSnkAugV, SrcNId, SnkNId); if (MinAug == 0) { break; } MaxFlow += MinAug; CurNId = SrcNId; for (int i = MidToSrcAugV.Len() - 1; i >= 0; i--) { int NextEId = MidToSrcAugV[i]; const TNEANet::TEdgeI &EI = Net->GetEI(NextEId); if (EI.GetSrcNId() == CurNId) { Flow[NextEId] += MinAug; CurNId = EI.GetDstNId(); } else { Flow[NextEId] -= MinAug; CurNId = EI.GetSrcNId(); } } for (int i = 0; i < MidToSnkAugV.Len(); i++) { int NextEId = MidToSnkAugV[i]; const TNEANet::TEdgeI &EI = Net->GetEI(NextEId); if (EI.GetSrcNId() == CurNId) { Flow[NextEId] += MinAug; CurNId = EI.GetDstNId(); } else { Flow[NextEId] -= MinAug; CurNId = EI.GetSrcNId(); } } } return MaxFlow; }