Pagini recente » Cod sursa (job #2089919) | Cod sursa (job #43144) | Cod sursa (job #1283690) | Cod sursa (job #307101) | Cod sursa (job #2957869)
#include <fstream>
#include <limits>
#include <queue>
#include <vector>
using std::vector;
using Node = int;
const int INF = std::numeric_limits<int>::max();
class FlowNetwork {
private:
vector<vector<int>> capacityMatrix;
vector<vector<Node>> adjList;
int findFlowPath(Node s, Node t, vector<Node> &predInPath) {
std::fill(predInPath.begin(), predInPath.end(), -1);
predInPath[s] = -2;
struct QueueEntry {
Node node;
int flow;
};
std::queue<QueueEntry> bfsQueue;
bfsQueue.push({s, INF});
while (!bfsQueue.empty()) {
auto [node, flow] = bfsQueue.front();
bfsQueue.pop();
for (auto to : adjList[node]) {
// Skip visited nodes and saturated edges
if (predInPath[to] != -1 || capacityMatrix[node][to] == 0)
continue;
predInPath[to] = node;
int newFlow = std::min(flow, capacityMatrix[node][to]);
if (to == t) {
return newFlow;
}
bfsQueue.push({to, newFlow});
}
}
return 0;
}
public:
explicit FlowNetwork(int nodeCount) {
capacityMatrix.resize(nodeCount, vector<int>(nodeCount));
adjList.resize(nodeCount);
}
void addEdge(Node from, Node to, int capacity) {
adjList[from].push_back(to);
capacityMatrix[from][to] = capacity;
}
int maxFlow(Node s, Node t) {
int maxFlow = 0;
vector<Node> predInPath(adjList.size());
int newFlow;
while ((newFlow = findFlowPath(s, t, predInPath)) > 0) {
maxFlow += newFlow;
Node current = t;
while (current != s) {
Node pred = predInPath[current];
capacityMatrix[pred][current] -= newFlow;
capacityMatrix[current][pred] += newFlow;
current = pred;
}
}
return maxFlow;
}
};
int main() {
std::ifstream fin("maxflow.in");
int nodeCount, edgeCount;
fin >> nodeCount >> edgeCount;
FlowNetwork network(nodeCount + 1);
for (int i = 0; i < edgeCount; ++i) {
Node from, to;
int cap;
fin >> from >> to >> cap;
network.addEdge(from, to, cap);
}
fin.close();
std::ofstream fout("maxflow.out");
fout << network.maxFlow(1, nodeCount) << '\n';
fout.close();
return 0;
}