Pagini recente » Cod sursa (job #673318) | Cod sursa (job #1834598) | Cod sursa (job #2006301) | Cod sursa (job #1057972) | Cod sursa (job #1862280)
#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
template <bool Directed>
class flowNetwork {
private:
class Edge {
public:
int From;
int To;
int Capacity;
int Flow;
Edge(
int __From = 0,
int __To = 0,
int __Capacity = 0,
int __Flow = 0
) {
From = __From;
To = __To;
Capacity = __Capacity;
Flow = __Flow;
}
};
int Size;
int Source;
int Sink;
int numEdges;
vector <Edge> Edges;
vector <vector <int>> G;
static const int INF = numeric_limits <int> :: max();
inline void linkNodes(int x, int y, int c) {
Edges.push_back(Edge(x, y, c, 0));
G[x].push_back(numEdges);
numEdges++;
Edges.push_back(Edge(y, x, (Directed == true ? 0 : c), 0));
G[y].push_back(numEdges);
numEdges++;
}
pair <bool, vector <int>> findPath() {
vector <int> Parent(Size, -1);
queue <int> Q;
Parent[Source] = 0;
for (Q.push(Source); Q.empty() == false; Q.pop()) {
int x = Q.front();
if (x != Sink) {
for (int i: G[x]) {
if (Edges[i].Flow < Edges[i].Capacity) {
int y = Edges[i].To;
if (Parent[y] == -1) {
Parent[y] = i;
Q.push(y);
}
}
}
}
}
Parent[Source] = -1;
if (Parent[Sink] != -1) return {true, Parent};
else return {false, vector <int>()};
}
public:
flowNetwork(
const int __Size,
const int __Source,
const int __Sink,
const vector <pair <int, pair <int, int>>> &Edges
) {
Size = __Size;
Source = __Source;
Sink = __Sink;
numEdges = 0;
G = vector <vector <int>>(Size, vector <int>());
for (const pair <int, pair <int, int>> &Edge: Edges) {
int x;
int y;
int c = Edge.fi;
tie(x, y) = Edge.se;
linkNodes(x, y, c);
}
}
int flowSolve() {
int flowSum = 0;
bool Stop = false;
do {
bool foundSolution;
vector <int> Parent;
tie(foundSolution, Parent) = findPath();
if (foundSolution == false) {
Stop = true;
}
else {
for (int i: G[Sink]) {
if (Parent[Edges[i].To] != -1) {
int flowCurrent = INF;
Parent[Sink] = i ^ 1;
for (int j = Parent[Sink]; j != -1; j = Parent[Edges[j].From]) {
flowCurrent = min(flowCurrent, Edges[j].Capacity - Edges[j].Flow);
}
for (int j = Parent[Sink]; j != -1; j = Parent[Edges[j].From]) {
Edges[j].Flow += flowCurrent;
Edges[j ^ 1].Flow -= flowCurrent;
}
flowSum += flowCurrent;
}
}
}
} while (Stop == false);
return flowSum;
}
};
int n;
int m;
vector <pair <int, pair <int, int>>> Edges;
int main() {
ifstream cin("maxflow.in");
ofstream cout("maxflow.out");
cin >> n;
cin >> m;
for (int i = 1; i <= m; i++) {
int x;
int y;
int c;
cin >> x >> y >> c;
Edges.push_back({c, {x, y}});
}
flowNetwork <true> F(n + 1, 1, n, Edges);
cout << F.flowSolve() << "\n";
return 0;
}