Pagini recente » Cod sursa (job #1398758) | Cod sursa (job #1827250) | Cod sursa (job #11017) | Cod sursa (job #2205359) | Cod sursa (job #2658894)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
#include <utility>
#include <limits>
#include <chrono>
using namespace std;
using namespace std::chrono;
using Ip = pair <int, int>;
using Vip = vector <Ip>;
using Vi = vector <int>;
using V2i = vector <Vi>;
using Vi64 = vector <int64_t>;
using Qi = queue <int>;
constexpr int64_t Inf = 1LL * numeric_limits <int>::max ();
ifstream fin ("maxflow.in");
ofstream fout ("maxflow".out");
template <class T = int64_t>
class Dinic {
public:
Dinic (int n, int s, int t):
V (n), Source (s), Sink (t) {
Adj.resize (V), Level.resize (V), Ptr.resize (V);
}
void addEdge (int u, int v, T cap) {
if (u == v) return;
Edges.emplace_back (u, v, cap);
Adj[u].emplace_back ((int)Edges.size () - 1);
Edges.emplace_back (v, u, 0LL);
Adj[v].emplace_back ((int)Edges.size () - 1);
}
T maxFlow () {
T flow = 0LL;
while (true) {
fill (Level.begin (), Level.end (), -1);
Level[Source] = 0, Q.push (Source);
if (!bfs ()) break;
fill (Ptr.begin (), Ptr.end (), 0);
while (T pushed = dfs (Source, Inf))
flow += pushed;
}
return flow;
}
private:
class FlowEdge {
public:
FlowEdge (int from, int to, T capacity):
from (from), to (to), capacity (capacity) {
}
private:
int from, to;
T capacity, flow = 0LL;
friend Dinic;
};
using Vf = vector <FlowEdge>;
Vf Edges;
V2i Adj;
int V, Source, Sink;
Vi Level, Ptr;
Qi Q;
bool bfs () {
while (!Q.empty ()) {
int v = Q.front (); Q.pop ();
for (const auto& it: Adj[v]) {
if (Level[Edges[it].to] != -1 || Edges[it].capacity - Edges[it].flow < 1LL) continue;
Level[Edges[it].to] = Level[v] + 1;
Q.push (Edges[it].to);
}
}
return Level[Sink] != -1;
}
T dfs (int v, T pushed) {
if (!pushed) return 0LL;
if (v == Sink) return pushed;
for (int& cit = Ptr[v]; cit < (int)Adj[v].size (); ++ cit) {
int it = Adj[v][cit], u = Edges[it].to;
if (Level[u] != Level[v] + 1 || Edges[it].capacity - Edges[it].flow < 1LL) continue;
T send = dfs (u, min (pushed, Edges[it].capacity - Edges[it].flow));
if (!send) continue;
Edges[it].flow += send;
Edges[it ^ 1].flow -= send;
return send;
}
return 0LL;
}
};
int n, m, u, v;
int main () {
fin.sync_with_stdio (false), fin.tie (nullptr);
fout.sync_with_stdio (false), fout.tie (nullptr);
fin >> n >> m;
Dinic <int64_t> Graph (n, 0, n - 1);
for (int i = 0; i < m; ++ i) {
fin >> u >> v >> w; -- u, -- v;
Graph.addEdge (u, v, w);
}
fout << Graph.maxFlow ();
fin.close (), fout.close ();
return 0;
}