Pagini recente » Cod sursa (job #2146280) | Cod sursa (job #537059) | Cod sursa (job #2431492) | Cod sursa (job #95831) | Cod sursa (job #1461583)
#include <cstdio>
#include <cassert>
#include <algorithm>
#include <vector>
#include <list>
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
#define INFINIT 120000
#define MAXEDGES 5100
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* p = new int(cap);
int* f = new int(0);
adiac[n1].push_back(edge(n2, p, f));
adiac[n2].push_back(edge(-n1, p, f));
}
int size() { return adiac.size() - 1; }
bool getAugmentingPath(int nod, int endNod, vector<char>& visited, vector<int*>& pathFlows, int& minFlow) {
visited[nod] = 1;
if (nod == endNod)
return true;
for (auto i = adiac[nod].begin(); i != adiac[nod].end(); ++i) {
int neigh = i->toNod > 0 ? i->toNod : -i->toNod;
if (visited[neigh])
continue;
bool isForwardArc = i->toNod > 0 ? true : false;
bool isAvailable = false;
if (isForwardArc && *(i->flow) < *(i->capacity)) {
isAvailable = true;
if (*(i->capacity) - *(i->flow) < minFlow)
minFlow = *(i->capacity) - *(i->flow);
}
else if (!isForwardArc && *(i->flow) > 0) {
isAvailable = true;
if (*(i->flow) < minFlow)
minFlow = *(i->flow);
*(i->flow) = -(*(i->flow));
}
if (isAvailable) {
if (getAugmentingPath(neigh, endNod, visited, pathFlows, minFlow)) {
pathFlows.push_back(i->flow);
return true;
}
}
}
return false;
}
int FordFulkerson(int source, int sink) {
int s = 0;
vector<int*> pathFlows;
pathFlows.reserve(MAXEDGES);
vector<char> visited(size() + 1);
while (true) {
int minFlow = INFINIT;
visited.assign(size() + 1, 0);
pathFlows.clear();
getAugmentingPath(source, sink, visited, pathFlows, minFlow);
if (!pathFlows.size())
break;
s += minFlow;
for (auto i = pathFlows.begin(); i != pathFlows.end(); ++i) {
if (**i < 0) {
**i = -(**i);
**i -= minFlow;
}
else
**i += minFlow;
}
}
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->FordFulkerson(1, N));
return 0;
}