1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
template<typename C>
bool getAugmentingPath(DiGraph<C>& g, std::vector<size_t>& path){ //bfs
std::vector<bool> visited(g.size(), false);
std::list<size_t> q; //create Queue
visited[0] = true; //mark source as visited and add to queue
q.push_back(0);
path[0] = 0;
while(!q.empty()){
int u;
u = q.front(); //remove front of queue
q.pop_front();
//check adjacent vertices
for(std::size_t v = 1; v<g.size(); v++){
if(visited[v] == false && g.getEdgeCapacity(u,v) != 0){
if(v == g.size()-1){
path[v] = u;
return true;
}
visited[v] = true;
q.push_back(v);
path[v] = u;
}
}
}
return false;
}
//Ford-Fulkerson
template<typename C>
void maxFlow(DiGraph<C>& g)
{
int u,v,a,b;
int n = g.size();
int MAX = std::numeric_limits<int>::max();
DiGraph<C> rGraph(n); //residual network
for(u=0; u<n; u++){ //transfer capacities
for(v=0; v<n; v++){
rGraph.setEdgeCapacity(u,v,g.getEdgeCapacity(u,v));
}
}
std::vector<size_t> path(n,0); //vector containing path found through BFS
for(int u=0; u<n; ++u){ //no flow initially
for(int v=0; v<n; ++v){
g.setFlowValue(u,v,0);
rGraph.setFlowValue(u,v,0);
}
}
while(getAugmentingPath(g, path))
{
int path_flow = MAX;
for(v=n-1; v!=0; v=path[v]){ //find maximal flow through path
u = path[v];
path_flow = std::min(path_flow, rGraph.getEdgeCapacity(u,v));
}
for(v = n-1; v!=0; v=path[v]){ //update flow
u = path[v];
a = rGraph.getFlowValue(u,v);
b = g.getFlowValue(u,v);
rGraph.setFlowValue(u,v,a-=path_flow);
g.setFlowValue(u,v,b+=path_flow);
}
}
}
|