Pagini recente » Cod sursa (job #1866593) | Cod sursa (job #2686293) | Cod sursa (job #1753194) | Cod sursa (job #661983) | Cod sursa (job #1198676)
#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),
G(vector< vector<int> >(_V, vector<int>())),
edges(vector<Edge>()) {}
void AddEdge(const Edge &edge) {
edges.push_back(edge);
G[edge.from].push_back(E++);
}
int MaximumFlow(const int source, const int sink) {
InitializeFlowNetwork();
int maximumFlow = 0;
vector<int> father;
while (BFS(source, sink, father)) {
for (vector<int>::const_iterator e = G[sink].begin(); e != G[sink].end(); ++e) {
if (edges[NonEdge(*e)].IsSaturated() || father[edges[*e].to] == NIL)
continue;
father[sink] = NonEdge(*e);
int currentFlow = Edge::MAX_CAPACITY;
for (int x = sink; x != source; x = edges[father[x]].from)
currentFlow = min(currentFlow, edges[father[x]].capacity - edges[father[x]].flow);
for (int x = sink; x != source; x = edges[father[x]].from) {
edges[father[x]].flow += currentFlow;
edges[NonEdge(father[x])].flow -= currentFlow;
}
maximumFlow += currentFlow;
}
}
ClearResidualNetwork();
return maximumFlow;
}
private:
int V, E;
vector< vector<int> > G;
vector<Edge> edges;
int NonEdge(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) const {
father = vector<int>(V, NIL);
father[source] = 2 * E;
queue<int> q;
for (q.push(source); !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() && father[edges[*e].to] == NIL) {
father[edges[*e].to] = *e;
q.push(edges[*e].to);
}
}
}
return father[destination] != NIL;
}
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(NonEdge(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;
}