Pagini recente » Cod sursa (job #488954) | Cod sursa (job #2398014) | Cod sursa (job #1629342) | Cod sursa (job #2634787) | Cod sursa (job #3153565)
#include <bits/stdc++.h>
using namespace std;
constexpr long long INF = 1e18;
struct FlowEdge {
int from, to;
long long capacity;
long long flow;
inline FlowEdge(int from, int to, long long capacity)
: from(from), to(to), capacity(capacity), flow() {}
};
class Dinitz {
vector<FlowEdge> edges;
vector<vector<int>> inc;
vector<int> level, ptr;
int V, E, s, t, max_f;
bool solved;
inline bool generate_level_graph() {
fill(level.begin(), level.end(), -1);
level[s] = 0;
queue<int> q;
q.push(s);
while (!q.empty()) {
const int node = q.front();
q.pop();
for (const int id : inc[node]) {
if (edges[id].capacity - edges[id].flow == 0) continue;
if (level[edges[id].to] != -1) continue;
level[edges[id].to] = level[node] + 1;
q.push(edges[id].to);
}
}
return level[t] != -1;
}
inline long long find_augmenting_path(int node, long long pushed = INF) {
if (node == t || pushed == 0) return pushed;
for (; ptr[node] < (int)inc[node].size(); ++ptr[node]) {
const int id = inc[node][ptr[node]];
const int to = edges[id].to;
if (level[node] + 1 != level[to] || edges[id].capacity - edges[id].flow == 0)
continue;
long long tr = find_augmenting_path(to, min(pushed, edges[id].capacity - edges[id].flow));
if (tr == 0) continue;
edges[id].flow += tr;
edges[id ^ 1].flow -= tr;
return tr;
}
return 0;
}
public:
Dinitz(int V, int s, int t)
: V(V), E(), s(s), t(t), solved(false) {
inc.resize(V);
level.resize(V);
ptr.resize(V);
}
inline void add_edge(int from, int to, long long capacity) {
edges.emplace_back(from, to, capacity);
edges.emplace_back(to, from, 0);
inc[from].push_back(E);
inc[to].push_back(E + 1);
E += 2;
solved = false;
}
inline long long max_flow() {
if (solved) return max_f;
for (FlowEdge &edge : edges)
edge.flow = 0;
long long f = 0;
for (;;) {
fill(level.begin(), level.end(), -1);
if (!generate_level_graph())
break;
fill(ptr.begin(), ptr.end(), 0);
while (long long pushed = find_augmenting_path(s))
f += pushed;
}
solved = true;
return max_f = f;
}
};
int main() {
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
int V, E;
fin >> V >> E;
vector<FlowEdge> edges;
vector<int> in(V, 0), out(V, 0);
int from, to, capacity;
for (int i = 0; i < E; ++i) {
fin >> from >> to >> capacity;
edges.emplace_back(from - 1, to - 1, capacity);
++out[from - 1];
++in[to - 1];
}
int s, t;
for (int i = 0; i < V; ++i)
if (in[i] == 0) s = i;
else if (out[i] == 0) t = i;
Dinitz dinitz(V, s, t);
for (const FlowEdge &edge : edges)
dinitz.add_edge(edge.from, edge.to, edge.capacity);
fout << dinitz.max_flow();
fin.close();
fout.close();
return 0;
}