Pagini recente » Cod sursa (job #2932495) | Cod sursa (job #104961) | Cod sursa (job #1971264) | Cod sursa (job #876912) | Cod sursa (job #2981898)
#include <cstdio>
#include <memory>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
class Solver{
private:
void buildResidualGraph(const vector<tuple<int,int,int>> edges, int N) {
Graph.resize(N);
Capacity.resize(N, vector<int>(N));
Flow.resize(N, vector<int>(N));
Visited.resize(N);
Parent.resize(N);
for (auto [from, to, capacity]: edges) {
Graph[from].emplace_back(to);
Graph[to].emplace_back(from);
Capacity[from][to] += capacity;
}
}
bool BFS(int source, int sink) {
queue<int> Q;
fill(Visited.begin(), Visited.end(), false);
int k = source;
Q.emplace(k);
Visited[k] = true;
bool foundSomePath = false;
while (!Q.empty()) {
k = Q.front(); Q.pop();
if (k == sink) {
foundSomePath = true;
continue;
}
for (auto v: Graph[k])
if (!Visited[v] && Capacity[k][v] > Flow[k][v]) {
Visited[v] = true;
Q.emplace(v);
Parent[v] = k;
}
}
return foundSomePath;
}
int maxFlow(const vector<tuple<int,int,int>>& edges, int N, int source, int sink) {
int total = 0, crtFlow;
buildResidualGraph(edges, N);
while (BFS(source, sink))
for (auto v: Graph[sink])
if (Visited[v]) { // if v is a node that we found a path through
crtFlow = Capacity[v][sink] - Flow[v][sink];
for (int crtNode = v; crtNode != source && crtFlow; crtNode = Parent[crtNode])
crtFlow = min(crtFlow, Capacity[Parent[crtNode]][crtNode] - Flow[Parent[crtNode]][crtNode]);
if (!crtFlow)
continue;
for (int crtNode = v; crtNode != source; crtNode = Parent[crtNode]) {
Flow[Parent[crtNode]][crtNode] += crtFlow;
Flow[crtNode][Parent[crtNode]] -= crtFlow;
}
total += crtFlow;
}
return total;
}
vector<vector<int>> Graph; // Graph[i] = nodes adjacent to i
vector<vector<int>> Capacity; // Capacity[i][j] = space from i to j
vector<vector<int>> Flow; // Flow[i][j] = how much flows between i and j
vector<int> Parent; // Parent[i] = previous node in the BFS on residual graph
vector<bool> Visited; // Visited[i] = whether the node in the residual graph was visited during last BFS
public:
Solver() {
freopen("maxflow.in", "r", stdin);
freopen("maxflow.out", "w", stdout);
}
~Solver() {
fclose(stdin);
fclose(stdout);
}
void execute() {
int N, M;
scanf("%d%d", &N, &M);
vector<tuple<int,int,int>> edges;
int from, to, capacity;
for (int i = 0; i < M; ++i) {
scanf("%d%d%d", &from, &to, &capacity);
--from; --to;
edges.emplace_back(from, to, capacity);
}
printf("%d\n", maxFlow(edges, N, 0, N - 1));
}
};
int main() {
unique_ptr<Solver> s = make_unique<Solver>();
s->execute();
return 0;
}