Pagini recente » Cod sursa (job #1577635) | Cod sursa (job #2308918) | Cod sursa (job #713467) | Cod sursa (job #386119) | Cod sursa (job #1112344)
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
class Graph {
public:
class Edge {
public:
static const int oo = 0x3f3f3f3f;
Edge(const int _from, const int _to, const int _capacity):
from(_from),
to(_to),
capacity(_capacity),
flow(0) {}
int From() const {
return from;
}
int To() const {
return to;
}
int Capacity() const {
return capacity;
}
int &Flow() {
return flow;
}
bool IsSaturated() const {
return flow == capacity;
}
private:
int from, to, capacity, flow;
};
static const int NIL = -1;
Graph(const int _v = 0):
v(_v),
edgeCount(0),
vertexEdges(vector< vector<int> >(_v, vector<int>())),
edges(vector<Edge>()) {}
int V() const {
return v;
}
Edge GetEdge(const int e) const {
return edges[e];
}
vector<int>::const_iterator EdgesBegin(const int x) const {
return vertexEdges[x].begin();
}
vector<int>::const_iterator EdgesEnd(const int x) const {
return vertexEdges[x].end();
}
void AddEdge(const Edge &e) {
vertexEdges[e.From()].push_back(edgeCount++);
edges.push_back(e);
}
int MaximumFlow(const int source, const int sink) {
InitializeFlowNetwork();
int maxFlow = 0;
vector<int> father;
while (BFS(source, sink, father)) {
for (vector<int>::iterator e = vertexEdges[sink].begin(); e != vertexEdges[sink].end(); ++e) {
if (father[edges[*e].To()] == NIL || edges[NonEdge(*e)].IsSaturated())
continue;
father[sink] = NonEdge(*e);
int currentFlow = Edge::oo;
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;
}
maxFlow += currentFlow;
}
}
ClearFlowNetwork();
return maxFlow;
}
private:
int v, edgeCount;
vector< vector<int> > vertexEdges;
vector<Edge> edges;
int NonEdge(const int e) const {
if (e < edgeCount)
return e + edgeCount;
else
return e - edgeCount;
}
void InitializeFlowNetwork() {
for (int e = 0; e < edgeCount; ++e) {
edges[e].Flow() = 0;
edges.push_back(Edge(edges[e].To(), edges[e].From(), 0));
vertexEdges[edges[e].To()].push_back(NonEdge(e));
}
}
bool BFS(const int source, const int sink, vector<int> &father) const {
father = vector<int>(v, NIL);
father[source] = 2 * edgeCount;
queue<int> q;
for (q.push(source); !q.empty(); q.pop()) {
int x = q.front();
if (x == sink)
continue;
for (vector<int>::const_iterator e = vertexEdges[x].begin(); e != vertexEdges[x].end(); ++e) {
if (father[edges[*e].To()] == NIL && !edges[*e].IsSaturated()) {
father[edges[*e].To()] = *e;
q.push(edges[*e].To());
}
}
}
return (father[sink] != NIL);
}
void ClearFlowNetwork() {
for (int e = edgeCount - 1; e >= 0; --e)
vertexEdges[edges[e].To()].pop_back();
for (int e = 0; e < edgeCount; ++e)
edges.pop_back();
}
};
Graph G;
int MaxFlow;
void Solve() {
MaxFlow = G.MaximumFlow(0, G.V() - 1);
}
void Read() {
ifstream cin("maxflow.in");
int v, e;
cin >> v >> e;
G = Graph(v);
for (; e > 0; --e) {
int from, to, capacity;
cin >> from >> to >> capacity;
G.AddEdge(Graph::Edge(--from, --to, capacity));
}
cin.close();
}
void Print() {
ofstream cout("maxflow.out");
cout << MaxFlow << "\n";
cout.close();
}
int main() {
Read();
Solve();
Print();
return 0;
}