Pagini recente » Cod sursa (job #2961258) | Cod sursa (job #2471197) | Monitorul de evaluare | Cod sursa (job #3032528) | Cod sursa (job #1333447)
#include <bits/stdc++.h>
using namespace std;
class MaxFlowNetwork {
private:
typedef long long i64;
class Edge {
public:
int to;
i64 cap, flow;
Edge* rev;
Edge(const int _to, const i64 _cap, const i64 _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, i64 cap, i64 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);
}
i64 maxFlow(int S, int D, bool clearFlow = true) {
i64 flow = 0;
while (bfs(S, D)) {
for (Edge* p: G[D]) {
if (p->rev->cap == p->rev->flow || father[p->to] == NULL) continue;
i64 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 i64 Inf = 1LL << 62;
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) continue;
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();
}