Differences From Artifact [aeb9a52588e83f01]:
- File
lib/graph/maxFlow.cpp
- 2012-05-20 14:30:32 - part of checkin [5919ac5f24] on branch trunk - 2048 (user: kinaba) [annotate]
To Artifact [f71eec6e87c84091]:
- File
lib/graph/maxFlow.cpp
- 2019-11-16 01:13:10 - part of checkin [5e9a43e520] on branch trunk - mf (user: kinaba) [annotate]
2 //------------------------------------------------------------- 2 //-------------------------------------------------------------
3 // Dinic's Algorithm 3 // Dinic's Algorithm
4 // O(V E) 4 // O(V E)
5 // 5 //
6 // G : bidirectional (G[i].has(j) <==> G[j].has(i)) 6 // G : bidirectional (G[i].has(j) <==> G[j].has(i))
7 // F : flow-capacity F[i][j] = Capacity, F[j][i] = 0 7 // F : flow-capacity F[i][j] = Capacity, F[j][i] = 0
8 // 8 //
9 // Verified by | 9 // Old versoin Verified by
10 // - SRM 399 Div1 LV3 10 // - SRM 399 Div1 LV3
11 // - PKU 1459 11 // - PKU 1459
12 // - CodeCraft 09 CUTS 12 // - CodeCraft 09 CUTS
13 // - SRM 465 Div1 LV2 13 // - SRM 465 Div1 LV2
14 // - SRM 543 Div1 LV3 14 // - SRM 543 Div1 LV3
15 //------------------------------------------------------------- 15 //-------------------------------------------------------------
16 16
................................................................................................................................................................................
24 if( !v2id_.count(v) ) { v2id_[v] = size(); id2v_.push_back(v); } 24 if( !v2id_.count(v) ) { v2id_[v] = size(); id2v_.push_back(v); }
25 return v2id_[v]; 25 return v2id_[v];
26 } 26 }
27 const T& id2v(int i) const { return id2v_[i]; } 27 const T& id2v(int i) const { return id2v_[i]; }
28 int size() const { return id2v_.size(); } 28 int size() const { return id2v_.size(); }
29 }; 29 };
30 30
31 template<typename Vert, typename Flow, int NV=2048> | 31 template<typename Vert, typename Flow, int NV=50*50*8+2>
32 class MaxFlow 32 class MaxFlow
33 { 33 {
> 34 typedef int Edge;
> 35
> 36 vector<int> G[NV];
> 37 vector<Flow> F;
> 38
34 IdGen<Vert> idgen; 39 IdGen<Vert> idgen;
> 40 map<pair<int,int>, Edge> edge_id;
35 vector<int> G[NV]; | 41 vector<int> Edge_to;
36 Flow F[NV][NV]; <
> 42 vector<Edge> Edge_rev;
37 43
38 public: 44 public:
39 void addEdge( Vert s_, Vert t_, Flow f ) | 45 void add( Vert s_, Vert t_, Flow f )
40 { 46 {
41 const int s = idgen.v2id(s_), t = idgen.v2id(t_); 47 const int s = idgen.v2id(s_), t = idgen.v2id(t_);
> 48 if(!edge_id.count(make_pair(s,t))) {
> 49 const int e = int(edge_id.size());
> 50 edge_id[make_pair(s,t)] = e;
> 51 edge_id[make_pair(t,s)] = e+1;
42 G[s].push_back(t); | 52 G[s].push_back(e);
43 G[t].push_back(s); | 53 G[t].push_back(e+1);
44 F[s][t] = f; <
45 F[t][s] = 0; <
> 54 F.push_back(0);
> 55 F.push_back(0);
> 56 Edge_rev.push_back(e+1);
> 57 Edge_rev.push_back(e);
> 58 Edge_to.push_back(t);
> 59 Edge_to.push_back(s);
> 60 }
> 61 const Edge e = edge_id[make_pair(s,t)];
> 62 F[e] = min(F[e]+f, INF);
46 } 63 }
47 64
48 Flow calc( Vert s_, Vert t_ ) 65 Flow calc( Vert s_, Vert t_ )
49 { 66 {
50 const int S = idgen.v2id(s_), D = idgen.v2id(t_); 67 const int S = idgen.v2id(s_), D = idgen.v2id(t_);
51 for( Flow total=0 ;; ) { 68 for( Flow total=0 ;; ) {
52 // Do BFS and compute the level for each node. 69 // Do BFS and compute the level for each node.
53 int LV[NV] = {0}; 70 int LV[NV] = {0};
54 vector<int> Q(1, S); 71 vector<int> Q(1, S);
55 for(int lv=1; !Q.empty(); ++lv) { 72 for(int lv=1; !Q.empty(); ++lv) {
56 vector<int> Q2; 73 vector<int> Q2;
57 for(size_t i=0; i!=Q.size(); ++i) { 74 for(size_t i=0; i!=Q.size(); ++i) {
58 const vector<int>& ne = G[Q[i]]; | 75 const vector<Edge>& ne = G[Q[i]];
59 for(size_t j=0; j!=ne.size(); ++j) | 76 for(size_t j=0; j!=ne.size(); ++j) {
60 if( F[Q[i]][ne[j]] && !LV[ne[j]] | 77 Edge e = ne[j];
> 78 int t = Edge_to[e];
> 79 if( F[e] && !LV[t] && t!=S )
61 LV[ne[j]]=lv, Q2.push_ba | 80 LV[t]=lv, Q2.push_back(t
> 81 }
62 } 82 }
63 Q.swap(Q2); 83 Q.swap(Q2);
64 } 84 }
65 85
66 // Destination is now unreachable. Done. 86 // Destination is now unreachable. Done.
67 if( !LV[D] ) 87 if( !LV[D] )
68 return total; 88 return total;
69 89
70 // Iterating DFS. 90 // Iterating DFS.
71 bool blocked[NV] = {}; 91 bool blocked[NV] = {};
72 total += dinic_dfs( S, D, LV, 0x7fffffff, blocked ); | 92 total += dinic_dfs( S, D, LV, INF, blocked );
73 } 93 }
74 } 94 }
75 95
76 private: 96 private:
77 Flow dinic_dfs( int v, int D, int LV[], Flow flow_in, bool blocked[] ) 97 Flow dinic_dfs( int v, int D, int LV[], Flow flow_in, bool blocked[] )
78 { 98 {
79 Flow flow_out = 0; 99 Flow flow_out = 0;
80 for(size_t i=0; i!=G[v].size(); ++i) { 100 for(size_t i=0; i!=G[v].size(); ++i) {
81 int u = G[v][i]; | 101 Edge e = G[v][i];
> 102 int u = Edge_to[e];
82 if( LV[v]+1==LV[u] && F[v][u] ) { | 103 if( LV[v]+1==LV[u] && F[e] ) {
83 Flow f = min(flow_in-flow_out, F[v][u]); | 104 Flow f = min(flow_in-flow_out, F[e]);
84 if( u==D || !blocked[u] && (f=dinic_dfs(u,D,LV,f 105 if( u==D || !blocked[u] && (f=dinic_dfs(u,D,LV,f
85 F[v][u] -= f; | 106 F[e] -= f;
86 F[u][v] += f; | 107 F[Edge_rev[e]] += f;
87 flow_out += f; 108 flow_out += f;
88 if( flow_in == flow_out ) return flow_ou 109 if( flow_in == flow_out ) return flow_ou
89 } 110 }
90 } 111 }
91 } 112 }
92 blocked[v] = (flow_out==0); 113 blocked[v] = (flow_out==0);
93 return flow_out; 114 return flow_out;
94 } 115 }
95 }; 116 };