Pagini recente » Cod sursa (job #1455511) | Cod sursa (job #197801) | Cod sursa (job #822167) | Cod sursa (job #32757) | Cod sursa (job #1333535)
#include <bits/stdc++.h>
using namespace std;
class MaxFlowNetwork {
private:
typedef long long i64;
class Edge {
public:
int to;
int cap, flow;
Edge* rev;
Edge(const int _to, const int _cap, const int _flow):
to(_to), cap(_cap), flow(_flow) {}
};
public:
MaxFlowNetwork(const int N):
G(vector<vector<Edge*>>(N)), father(vector<Edge*>(N)), NIL(new Edge(0, 0, 0)) {
}
~MaxFlowNetwork() {
for (auto& p: G)
for (Edge* l: p)
delete l;
delete NIL;
}
void addEdge(int x, int y, int cap, int flow = 0) {
Edge* add = new Edge(y, cap, flow);
Edge* rev = new Edge(x, 0, -flow);
add->rev = rev; rev->rev = add;
G[x].push_back(add);
G[y].push_back(rev);
}
int maxFlow(int S, int D, bool clearFlow = true) {
int flow = 0;
for (int i = 0; i < int(G.size()); ++i) {
vector<Edge*> zero, nonZero;
for (Edge* p: G[i])
if (p->cap == 0) zero.push_back(p);
else nonZero.push_back(p);
G[i] = nonZero;
for (Edge* p: zero) G[i].push_back(p);
}
while (bfs(S, D)) {
for (Edge* p: G[D]) {
if (p->rev->cap == p->rev->flow || father[p->to] == NULL) continue;
father[D] = p;
int fmin = MaxFlowNetwork::Inf;
for (int i = D; i != S; i = father[i]->to)
fmin = min(fmin, father[i]->rev->cap - father[i]->rev->flow);
flow += fmin;
for (int i = D; i != S; i = father[i]->to) {
father[i]->rev->flow += fmin;
father[i]->flow -= fmin;
}
}
}
if (clearFlow) {
fill(father.begin(), father.end(), (Edge*)NULL);
dfsClear(S);
}
return flow;
}
private:
const static int Inf = 0x3f3f3f3f;
vector<vector<Edge*>> G;
vector<Edge*> father;
Edge* NIL;
bool bfs(int S, int D) {
fill(father.begin(), father.end(), (Edge*)NULL);
queue<int> Q;
Q.push(S);
father[S] = NIL;
while (!Q.empty()) {
int node = Q.front();
Q.pop();
if (node == D) continue;
for (Edge* p: G[node]) {
if (p->cap > p->flow && father[p->to] == NULL) {
father[p->to] = p->rev;
Q.push(p->to);
}
}
}
return father[D] != NULL;
}
void dfsClear(int node) {
father[node] = NIL;
for (Edge* p: G[node]) {
p->flow = 0;
if (father[p->to] != NIL)
dfsClear(p->to);
}
}
};
int main()
{
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
int N, M;
fin >> N >> M;
unique_ptr<MaxFlowNetwork> G(new MaxFlowNetwork(N));
while (M--) {
int x, y, cap;
fin >> x >> y >> cap;
G->addEdge(x - 1, y - 1, cap);
}
fout << G->maxFlow(0, N - 1, false) << '\n';
fin.close();
fout.close();
}