Pagini recente » Cod sursa (job #1129367) | Cod sursa (job #2224417) | Cod sursa (job #1755198) | Cod sursa (job #1449189) | Cod sursa (job #2885429)
#include <bits/stdc++.h>
using namespace std;
// #define int long long
template < typename EDGE_FLOW_DATA , typename NETWORK_FLOW_DATA >
struct Dinic {
struct Edge {
int to; EDGE_FLOW_DATA flow, cap;
};
const int MAXDIST = 1e9;
const NETWORK_FLOW_DATA MAXFLOW = std::numeric_limits<NETWORK_FLOW_DATA>::max();
int n, source, sink;
vector<vector<int>> adj;
vector<int> edge_ind, dist;
vector<Edge> edges;
Dinic(int _n, int _source, int _sink) {
n = _n; source = _source; sink = _sink;
adj.resize(n + 3); edge_ind.resize(n + 3); dist.resize(n + 3);
}
void add_edge(int from, int to, int cap) {
edges.push_back({.to=to, .flow=0, .cap=cap});
edges.push_back({.to=from, .flow=0, .cap=0});
adj[from].push_back(edges.size() - 2);
adj[to].push_back(edges.size() - 1);
}
bool do_bfs() {
for(auto &e : dist) e = MAXDIST;
queue<int> q; q.push(source);
dist[source] = 0;
while(!q.empty()) {
auto cnt = q.front(); q.pop();
for(auto ind : adj[cnt]) {
auto &e = edges[ind];
if(e.flow < e.cap && dist[e.to] > dist[cnt] + 1) {
dist[e.to] = dist[cnt] + 1;
q.push(e.to);
}
}
}
return dist[sink] != MAXDIST;
}
NETWORK_FLOW_DATA do_push(int node, NETWORK_FLOW_DATA flow) {
if(node == sink) return flow;
NETWORK_FLOW_DATA pushed = 0;
for(auto &ind = edge_ind[node]; ind < (int)adj[node].size(); ind++) {
if(flow == 0) return pushed;
auto &e = edges[adj[node][ind]];
if(dist[e.to] != dist[node] + 1) continue;
if(e.flow < e.cap) {
NETWORK_FLOW_DATA cnt_pushed = do_push(e.to, min<NETWORK_FLOW_DATA>(e.cap - e.flow, flow));
pushed += cnt_pushed; flow -= cnt_pushed;
// cerr << "Pushed from " << node << " to " << e.to << " some " << cnt_pushed << endl;
edges[adj[node][ind] ].flow += cnt_pushed;
edges[adj[node][ind] ^ 1].flow -= cnt_pushed;
}
}
return pushed;
}
NETWORK_FLOW_DATA get_flow() {
NETWORK_FLOW_DATA answer = 0;
while(do_bfs()) {
// for(int i = 1; i <= n; i++)
// cerr << i << ": " << dist[i] << endl;
for(auto &e : edge_ind) e = 0;
while(true) {
NETWORK_FLOW_DATA pushed = do_push(source, MAXFLOW);
answer += pushed;
if(pushed == 0) break;
}
}
return answer;
}
};
#ifndef LOCAL
ifstream in("maxflow.in");
ofstream out("maxflow.out");
#define cin in
#define cout out
#endif // LOCAL
int32_t main() {
int n, m; cin >> n >> m;
Dinic<int32_t, int64_t> solver(n, 1, n);
for(int i = 0; i < m; i++) {
int x, y, c; cin >> x >> y >> c;
solver.add_edge(x, y, c);
}
cout << solver.get_flow() << '\n';
}