Pagini recente » Cod sursa (job #1817660) | Cod sursa (job #2324668) | Cod sursa (job #1111254) | Cod sursa (job #789560) | Cod sursa (job #2813689)
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
const int N = 1e3 + 5;
struct Edge {
int from, to;
int cap;
};
class Dinic {
private:
vector<vector<int>> gr;
vector<Edge> ed;
int *nxtEdge, *lvl;
int nodeCnt, src, dst, maxFlow;
public:
Dinic(int n, int s, int d): nodeCnt(n), src(s), dst(d), maxFlow(0) {
gr = vector<vector<int>>(n + 1);
nxtEdge = new int[n + 1];
lvl = new int[n + 1];
}
void addEdge(int from, int to, int cap) {
ed.push_back({from, to, cap});
gr[from].push_back(ed.size() - 1);
ed.push_back({to, from, 0});
gr[to].push_back(ed.size() - 1);
}
bool bfs() {
queue<int> q;
q.push(src);
memset(lvl, 0, (nodeCnt + 1) * sizeof(int));
lvl[src] = 1;
while (!q.empty()) {
auto node = q.front();
q.pop();
if (node == dst)
break;
for (auto e: gr[node])
if (lvl[ed[e].to] == 0 && ed[e].cap > 0) {
lvl[ed[e].to] = lvl[node] + 1;
q.push(ed[e].to);
}
}
return lvl[dst] != 0;
}
int dfs(int node, int minFlow) {
if (node == dst)
return minFlow;
for (;nxtEdge[node] < gr[node].size(); ++nxtEdge[node]) {
int e = gr[node][nxtEdge[node]];
if (ed[e].cap == 0) continue;
if (lvl[ed[e].to] != lvl[node] + 1) continue;
int flow = dfs(ed[e].to, min(minFlow, ed[e].cap));
if (flow != -1) {
ed[e].cap -= flow;
ed[e ^ 1].cap += flow;
return flow;
}
}
return -1;
}
int getMaxFlow() {
while (bfs()) {
memset(nxtEdge, 0, (nodeCnt + 1) * sizeof(int));
int flow = dfs(src, 2e9);
while (flow != -1) {
maxFlow += flow;
flow = dfs(src, 2e9);
}
}
return maxFlow;
}
};
int main() {
ifstream cin("maxflow.in");
ofstream cout("maxflow.out");
int n, m;
cin >> n >> m;
Dinic d(n, 1, n);
while (m--) {
int x, y, c;
cin >> x >> y >> c;
d.addEdge(x, y, c);
}
cin.close();
cout << d.getMaxFlow() << "\n";
cout.close();
return 0;
}