Artifact 296b9275312ebbf1e64a9e94d6e99fdf47d1d6c2
//-------------------------------------------------------------
// Dinic's Algorithm
// O(V E)
//
// G : bidirectional (G[i].has(j) <==> G[j].has(i))
// F : flow-capacity F[i][j] = Capacity, F[j][i] = 0
//
// Verified by
// - SRM 399 Div1 LV3
// - PKU 1459
// - CodeCraft 09 CUTS
// - SRM 465 Div1 LV2
//-------------------------------------------------------------
template<typename T>
class IdGen
{
map<T, int> v2id_;
vector<T> id2v_;
public:
int v2id(const T& v) {
if( !v2id_.count(v) ) { v2id_[v] = size(); id2v_.push_back(v); }
return v2id_[v];
}
const T& id2v(int i) const { return id2v_[i]; }
int size() const { return id2v_.size(); }
};
template<typename Vert, typename Flow, int NV=512>
class MaxFlow
{
IdGen<Vert> idgen;
vector<int> G[NV];
Flow F[NV][NV];
public:
void addEdge( Vert s_, Vert t_, Flow f )
{
const int s = idgen.v2id(s_), t = idgen.v2id(t_);
G[s].push_back(t);
G[t].push_back(s);
F[s][t] = f;
F[t][s] = 0;
}
Flow calc( Vert s_, Vert t_ )
{
const int S = idgen.v2id(s_), D = idgen.v2id(t_);
for( Flow total=0 ;; ) {
// Do BFS and compute the level for each node.
int LV[NV] = {0};
vector<int> Q(1, S);
for(int lv=1; !Q.empty(); ++lv) {
vector<int> Q2;
for(size_t i=0; i!=Q.size(); ++i) {
const vector<int>& ne = G[Q[i]];
for(size_t j=0; j!=ne.size(); ++j)
if( F[Q[i]][ne[j]] && !LV[ne[j]] && ne[j]!=S )
LV[ne[j]]=lv, Q2.push_back(ne[j]);
}
Q.swap(Q2);
}
// Destination is now unreachable. Done.
if( !LV[D] )
return total;
// Iterating DFS.
bool blocked[NV] = {};
total += dinic_dfs( S, D, LV, 0x7fffffff, blocked );
}
}
private:
Flow dinic_dfs( int v, int D, int LV[], Flow flow_in, bool blocked[] )
{
Flow flow_out = 0;
for(size_t i=0; i!=G[v].size(); ++i) {
int u = G[v][i];
if( LV[v]+1==LV[u] && F[v][u] ) {
Flow f = min(flow_in-flow_out, F[v][u]);
if( u==D || !blocked[u] && (f=dinic_dfs(u,D,LV,f,blocked))>0 ) {
F[v][u] -= f;
F[u][v] += f;
flow_out += f;
if( flow_in == flow_out ) return flow_out;
}
}
}
blocked[v] = (flow_out==0);
return flow_out;
}
};