Pagini recente » Cod sursa (job #3128189) | Cod sursa (job #2416775) | Cod sursa (job #786098) | Cod sursa (job #2816088) | Cod sursa (job #1462050)
#include <cstdio>
#include <cassert>
#include <algorithm>
#include <vector>
#include <list>
#include <queue>
#include <cstdlib>
#include <cstring>
using namespace std;
#define _submit
#ifdef _submit
#define InFile "maxflow.in"
#define OtFile "maxflow.out"
#else
#define InFile "fis.in"
#define OtFile "fis.out"
#endif
class edge {
private:
int toNod, capacity, *flow;
edge(int N, int p, int* f) {
toNod = N;
capacity = p;
flow = f;
}
friend class graph;
};
class graph {
private:
vector< list<edge> > adiac;
public:
graph(int N) { adiac.resize(N + 1); }
void addEdge(int n1, int n2, int cap) {
int* f = new int(0);
adiac[n1].push_back(edge(n2, cap, f));
adiac[n2].push_back(edge(-n1, cap, f));
}
int size() { return adiac.size() - 1; }
int sendFlows(int nod, int endNod, vector<int> &parent, vector<int*> &flowArcToParent, vector<int> &capArcToParent, vector<char> &isForwardArc, queue<int>& Q) {
int s = 0;
memset(&parent[0], 0xFF, parent.size()*sizeof(parent[0]));
while (!Q.empty())
Q.pop();
Q.push(nod);
parent[nod] = 0;
while (!Q.empty()) {
int t = Q.front();
Q.pop();
for (auto i = adiac[t].begin(); i != adiac[t].end(); ++i) {
int curnod = i->toNod > 0 ? i->toNod : -(i->toNod);
if (curnod == endNod) {
int MF = i->capacity - *i->flow;
int aux = t;
while (parent[aux]) {
int availableFlow = isForwardArc[aux] ? capArcToParent[aux] - *flowArcToParent[aux] : *flowArcToParent[aux];
if (!availableFlow)
break;
if (availableFlow < MF)
MF = availableFlow;
aux = parent[aux];
}
if (!parent[aux]) {
if (i->toNod > 0)
*i->flow += MF;
else
*i->flow -= MF;
aux = t;
while (parent[aux]) {
if (isForwardArc[aux])
*flowArcToParent[aux] += MF;
else
*flowArcToParent[aux] -= MF;
aux = parent[aux];
}
}
s += MF;
}
else if (parent[curnod] == -1) {
int availableFlow = i->toNod > 0 ? i->capacity - *i->flow : *i->flow;
if (availableFlow) {
Q.push(curnod);
parent[curnod] = t;
flowArcToParent[curnod] = i->flow;
capArcToParent[curnod] = i->capacity;
if (i->toNod > 0)
isForwardArc[curnod] = 1;
else
isForwardArc[curnod] = 0;
}
}
}
}
return s;
}
int EdmondsKarp(int source, int sink) {
int s = 0;
vector<int> parent(size() + 1), caps(size() + 1);
vector<int*> flows(size() + 1);
vector<char> isForward(size() + 1);
queue<int> Q;
while (true) {
int flowSent = sendFlows(source, sink, parent, flows, caps, isForward, Q);
if (!flowSent)
break;
s += flowSent;
//fprintf(stderr, "%d\n", s);
}
return s;
}
};
int main() {
assert(freopen(InFile, "r", stdin));
assert(freopen(OtFile, "w", stdout));
int N, M;
scanf("%d%d", &N, &M);
graph* G = new graph(N);
for (int i = 0; i < M; i++) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
G->addEdge(a, b, c);
}
printf("%d\n", G->EdmondsKarp(1, N));
return 0;
}