Pagini recente » Cod sursa (job #2495180) | Cod sursa (job #670028) | Cod sursa (job #2889757) | Cod sursa (job #571276) | Cod sursa (job #3036871)
#include <stdio.h>
int min(int x, int y)
{
return x <= y ? x : y;
}
// performs Edmonds-Karp algorithm on a graph
struct EdmondsKarp
{
// the max. no. of edges and nodes
static const int EDGE_COUNT = 5000;
static const int NODE_COUNT = 1000;
// no node / no edge
static const int NONE = -1;
// infinity
static const int INF = 0x3f3f3f3f;
// the edges of the graph
struct
{
int v;
int capacity;
int next;
} edges[2 * EDGE_COUNT];
// the first edge of each node
int begin[NODE_COUNT];
// for each node, the edge to its parent in the BFS tree
int to_parent[NODE_COUNT];
// the no. of nodes and no. of edges
int n, m;
// the source and the sink
int source, sink;
// inits the graph with _n nodes and the given source and sink
void init(int _n, int _source, int _sink)
{
n = _n;
m = 0;
source = _source;
sink = _sink;
for(int i = 0; i < n; i++)
begin[i] = NONE;
}
// adds an edge from u to v with the given capacity
void add_edge(int u, int v, int capacity)
{
edges[m] = { v, capacity, begin[u] };
begin[u] = m++;
edges[m] = { u, 0, begin[v] };
begin[v] = m++;
}
// BFS to find augmenting paths
bool bfs()
{
static int queue[NODE_COUNT];
// init the parent edges
for(int i = 0; i < n; i++)
to_parent[i] = NONE;
to_parent[source] = INF;
// init the queue
int qfront = 0, qtop = 0;
queue[qtop++] = source;
// while the queue isn't empty and no path was found, propagate
while(qfront < qtop && to_parent[sink] == NONE)
{
int u = queue[qfront++];
for(int i = begin[u]; i != NONE; i = edges[i].next)
{
int v = edges[i].v;
if(edges[i].capacity != 0 && to_parent[v] == NONE)
{
queue[qtop++] = v;
to_parent[v] = (i ^ 1);
}
}
}
// return whether or not a path was found
return to_parent[sink] != NONE;
}
// augment the path according to the BFS tree found
int augment()
{
int flow = INF;
int v = sink;
// move back and calculate the flow
while(v != source)
{
int i = to_parent[v];
flow = min(flow, edges[i ^ 1].capacity);
v = edges[i].v;
}
// apply the flow
v = sink;
while(v != source)
{
int i = to_parent[v];
edges[i].capacity += flow;
edges[i ^ 1].capacity -= flow;
v = edges[i].v;
}
return flow;
}
// finds the max flow in the graph
int max_flow()
{
int flow = 0;
// while there are augmenting paths found
while(bfs())
flow += augment();
return flow;
}
};
EdmondsKarp flow;
int main()
{
// open the files
freopen("maxflow.in", "r", stdin);
freopen("maxflow.out", "w", stdout);
// read the graph
int n, m;
scanf("%d %d", &n, &m);
flow.init(n, 0, n - 1);
for(int i = 0; i < m; i++)
{
int u, v, capacity;
scanf("%d %d %d", &u, &v, &capacity);
u--; v--;
flow.add_edge(u, v, capacity);
}
// calculate and print the flow
printf("%d\n", flow.max_flow());
return 0;
}