Pagini recente » Cod sursa (job #2747467) | Cod sursa (job #1549184) | Cod sursa (job #2911216) | Cod sursa (job #2101467) | Cod sursa (job #1268898)
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
class Graph {
public:
static const int NIL = -1;
class Edge {
public:
static const int MAX_CAPACITY = 0x3f3f3f3f;
int from, to, capacity, flow;
Edge(const int _from, const int _to, const int _capacity):
from(_from),
to(_to),
capacity(_capacity),
flow(0) {}
bool IsSaturated() const {
return flow >= capacity;
}
};
Graph(const int _V = 0):
V(_V),
E(0),
edges(vector<Edge>()),
G(vector< vector<int> >(_V, vector<int>())) {}
void AddEdge(const Edge &e) {
G[e.from].push_back(E++);
edges.push_back(e);
}
int MaximumFlow(const int source, const int sink) {
InitializeFlowNetwork();
int maxFlow = 0;
vector<int> father;
vector<bool> visited;
while (BFS(source, sink, father, visited)) {
for (vector<int>::const_iterator e = G[sink].begin(); e != G[sink].end(); ++e) {
if (!edges[NonE(*e)].IsSaturated() && visited[edges[*e].to]) {
father[sink] = NonE(*e);
int flow = Edge::MAX_CAPACITY;
for (int x = sink; x != source; x = edges[father[x]].from)
flow = min(flow, edges[father[x]].capacity - edges[father[x]].flow);
for (int x = sink; x != source; x = edges[father[x]].from) {
edges[father[x]].flow += flow;
edges[NonE(father[x])].flow -= flow;
}
maxFlow += flow;
}
}
}
ClearResidualNetwork();
return maxFlow;
}
private:
int V, E;
vector<Edge> edges;
vector< vector<int> > G;
int NonE(const int e) const {
if (e < E)
return e + E;
else
return e - E;
}
bool BFS(const int source, const int destination, vector<int> &father, vector<bool> &visited) const {
father = vector<int>(V, NIL);
visited = vector<bool>(V, false);
queue<int> q;
visited[source] = true;
q.push(source);
for (; !q.empty(); q.pop()) {
int x = q.front();
if (x == destination)
continue;
for (vector<int>::const_iterator e = G[x].begin(); e != G[x].end(); ++e) {
if (!edges[*e].IsSaturated() && !visited[edges[*e].to]) {
visited[edges[*e].to] = true;
father[edges[*e].to] = *e;
q.push(edges[*e].to);
}
}
}
return visited[destination];
}
void InitializeFlowNetwork() {
for (int e = 0; e < E; ++e) {
edges[e].flow = 0;
edges.push_back(Edge(edges[e].to, edges[e].from, 0));
G[edges[e].to].push_back(NonE(e));
}
}
void ClearResidualNetwork() {
for (; int(edges.size()) > E; edges.pop_back())
G[edges.back().from].pop_back();
}
};
int main() {
ifstream cin("maxflow.in");
ofstream cout("maxflow.out");
int v, e;
cin >> v >> e;
Graph G = Graph(v);
for (; e > 0; --e) {
int from, to, capacity;
cin >> from >> to >> capacity;
G.AddEdge(Graph::Edge(from - 1, to - 1, capacity));
}
cout << G.MaximumFlow(0, v - 1) << "\n";
cin.close();
cout.close();
return 0;
}