4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: //------------------------------------------------------------- 4fd800b3a8 2011-02-23 kinaba: // Dinic's Algorithm 4fd800b3a8 2011-02-23 kinaba: // O(V E) 4fd800b3a8 2011-02-23 kinaba: // 4fd800b3a8 2011-02-23 kinaba: // G : bidirectional (G[i].has(j) <==> G[j].has(i)) 4fd800b3a8 2011-02-23 kinaba: // F : flow-capacity F[i][j] = Capacity, F[j][i] = 0 4fd800b3a8 2011-02-23 kinaba: // 4fd800b3a8 2011-02-23 kinaba: // Verified by 4fd800b3a8 2011-02-23 kinaba: // - SRM 399 Div1 LV3 4fd800b3a8 2011-02-23 kinaba: // - PKU 1459 4fd800b3a8 2011-02-23 kinaba: // - CodeCraft 09 CUTS 4fd800b3a8 2011-02-23 kinaba: // - SRM 465 Div1 LV2 4fd800b3a8 2011-02-23 kinaba: //------------------------------------------------------------- 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: static const int NV = 512; 4fd800b3a8 2011-02-23 kinaba: typedef int flow; 4fd800b3a8 2011-02-23 kinaba: typedef int vert; 4fd800b3a8 2011-02-23 kinaba: typedef vert edge; 4fd800b3a8 2011-02-23 kinaba: typedef vector<edge> edges; 4fd800b3a8 2011-02-23 kinaba: typedef vector<edges> graph; 4fd800b3a8 2011-02-23 kinaba: typedef flow flow_graph[NV][NV]; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: flow dinic_dfs( graph& G, flow_graph F, vert v, vert D, 4fd800b3a8 2011-02-23 kinaba: int LV[], flow flow_in, int blocked[] ) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: flow flow_out = 0; 4fd800b3a8 2011-02-23 kinaba: for(int i=0; i!=G[v].size(); ++i) { 4fd800b3a8 2011-02-23 kinaba: int u = G[v][i]; 4fd800b3a8 2011-02-23 kinaba: if( LV[v]+1==LV[u] && F[v][u] ) { 4fd800b3a8 2011-02-23 kinaba: flow f = min(flow_in-flow_out, F[v][u]); 4fd800b3a8 2011-02-23 kinaba: if( u==D || !blocked[u] && (f=dinic_dfs(G,F,u,D,LV,f,blocked)) ) { 4fd800b3a8 2011-02-23 kinaba: F[v][u] -= f; 4fd800b3a8 2011-02-23 kinaba: F[u][v] += f; 4fd800b3a8 2011-02-23 kinaba: flow_out += f; 4fd800b3a8 2011-02-23 kinaba: if( flow_in == flow_out ) return flow_out; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: blocked[v] = (flow_out==0); 4fd800b3a8 2011-02-23 kinaba: return flow_out; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: flow maxFlow( graph& G, flow_graph F, vert S, vert D ) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: for( flow total=0 ;; ) { 4fd800b3a8 2011-02-23 kinaba: int LV[NV] = {0}; 4fd800b3a8 2011-02-23 kinaba: vector<int> Q(1, S); 4fd800b3a8 2011-02-23 kinaba: for(int lv=1; !Q.empty(); ++lv) { 4fd800b3a8 2011-02-23 kinaba: vector<int> Q2; 4fd800b3a8 2011-02-23 kinaba: for(int i=0; i!=Q.size(); ++i) { 4fd800b3a8 2011-02-23 kinaba: edges& ne = G[Q[i]]; 4fd800b3a8 2011-02-23 kinaba: for(int j=0; j!=ne.size(); ++j) 4fd800b3a8 2011-02-23 kinaba: if( F[Q[i]][ne[j]] && !LV[ne[j]] && ne[j]!=S ) 4fd800b3a8 2011-02-23 kinaba: LV[ne[j]]=lv, Q2.push_back(ne[j]); 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: Q.swap(Q2); 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: if( !LV[D] ) 4fd800b3a8 2011-02-23 kinaba: return total; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: int blocked[NV] = {}; 4fd800b3a8 2011-02-23 kinaba: total += dinic_dfs( G, F, S, D, LV, 0x7fffffff, blocked ); 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: }