Pagini recente » Cod sursa (job #1126243) | Cod sursa (job #604457) | Cod sursa (job #569905) | Cod sursa (job #1218410) | Cod sursa (job #2205735)
#include <iostream>
#include <fstream>
#include <vector>
#include <cassert>
using namespace std;
ifstream in("maxflow.in");
const int INF = 110001;
const int N = 1001;
const int START_NODE = 1;
int END_NODE;
struct edge{
int current_flow = 0;
int max_flow;
bool edge_exists = false;
};
edge edges[N][N];
int n,m;
int node_path_colors[N];
int prev_path_node[N];
int crt_path_color = 0;
void find_augmenting_path_flow_value(int crt_node, int crt_path_color, int node_path_colors[]){
//cout<<"Visiting "<<crt_node<<"\n";
node_path_colors[crt_node] = crt_path_color;
for(int i=1; i<=n; ++i)
if(node_path_colors[i] != crt_path_color && /// Node hasn't been visited
((edges[crt_node][i].edge_exists && edges[crt_node][i].current_flow < edges[crt_node][i].max_flow) /// Can cross forwards
|| (edges[i][crt_node].edge_exists && edges[i][crt_node].current_flow > 0))) /// Can cross backwards
{
prev_path_node[i] = crt_node;
find_augmenting_path_flow_value(i, crt_path_color, node_path_colors);
}
}
int main()
{
/// Read
freopen("maxflow.out", "w", stdout);
in>>n>>m;
END_NODE = n;
for(int i=0; i<m; ++i){
int from, to, capacity;
in>>from>>to>>capacity;
edges[from][to].max_flow = capacity;
edges[from][to].edge_exists = true;
}
/// Solve
int maxFlow = 0;
while(1){
find_augmenting_path_flow_value(START_NODE, ++crt_path_color, node_path_colors);
if(node_path_colors[n] != crt_path_color) /// Final node hasn't been reached
break;
int crtNode;
int augmenting_flow = INF;
/// Find the augmenting flow
crtNode = n;
while(crtNode != START_NODE){
int prevNode = prev_path_node[crtNode];
int crt_augmenting_flow = INF;
if(edges[prevNode][crtNode].current_flow < edges[prevNode][crtNode].max_flow) /// Forward flow
crt_augmenting_flow = edges[prevNode][crtNode].max_flow - edges[prevNode][crtNode].current_flow;
else if(edges[crtNode][prevNode].current_flow > 0) /// Backwards flow
crt_augmenting_flow = edges[crtNode][prevNode].current_flow;
else /// Can't add a flow
assert(false); /// We have chained the two nodes because there is a flow we can add
augmenting_flow = min(augmenting_flow, crt_augmenting_flow);
crtNode = prevNode;
}
/// Add augmenting flow to our path
crtNode = n;
//cout<<crtNode<<" ";
while(crtNode != START_NODE){
int prevNode = prev_path_node[crtNode];
if(edges[prevNode][crtNode].current_flow < edges[prevNode][crtNode].max_flow) /// Forward flow
edges[prevNode][crtNode].current_flow += augmenting_flow;
else if(edges[crtNode][prevNode].current_flow > 0) /// Backwards flow
edges[crtNode][prevNode].current_flow -= augmenting_flow;
else /// Can't add a flow
assert(false); /// We have chained the two nodes because there is a flow we can add
crtNode = prevNode;
//cout<<crtNode<<" ";
}
//cout<<"\n";
maxFlow += augmenting_flow;
}
//cout<<"Max flow = "<<maxFlow<<"\n";
cout<<maxFlow;
return 0;
}