File Annotation
Not logged in
23dfcca431 2011-02-23        kinaba: //-------------------------------------------------------------
23dfcca431 2011-02-23        kinaba: // MinCost-MaxFlow
524cc07867 2012-04-03        kinaba: //   O(F E log E)    // F:flow
524cc07867 2012-04-03        kinaba: //   See http://d.hatena.ne.jp/tsukuno/20120320#1332179143
23dfcca431 2011-02-23        kinaba: //
23dfcca431 2011-02-23        kinaba: // Verified by
524cc07867 2012-04-03        kinaba: //   - (SRM 487 Div2 LV3) in previous version
524cc07867 2012-04-03        kinaba: //   - (SRM 526 Div1 LV1) in previous version
23dfcca431 2011-02-23        kinaba: //   - SRM 491 Div1 LV3
23dfcca431 2011-02-23        kinaba: //-------------------------------------------------------------
23dfcca431 2011-02-23        kinaba: 
23dfcca431 2011-02-23        kinaba: #include <iostream>
23dfcca431 2011-02-23        kinaba: #include <string>
23dfcca431 2011-02-23        kinaba: #include <vector>
23dfcca431 2011-02-23        kinaba: #include <map>
23dfcca431 2011-02-23        kinaba: #include <queue>
23dfcca431 2011-02-23        kinaba: using namespace std;
23dfcca431 2011-02-23        kinaba: 
23dfcca431 2011-02-23        kinaba: template<typename T>
23dfcca431 2011-02-23        kinaba: class IdGen
23dfcca431 2011-02-23        kinaba: {
23dfcca431 2011-02-23        kinaba: 	map<T, int> v2id_;
23dfcca431 2011-02-23        kinaba: 	vector<T>   id2v_;
23dfcca431 2011-02-23        kinaba: public:
23dfcca431 2011-02-23        kinaba: 	int v2id(const T& v) {
23dfcca431 2011-02-23        kinaba: 		if( !v2id_.count(v) ) { v2id_[v] = size(); id2v_.push_back(v); }
23dfcca431 2011-02-23        kinaba: 		return v2id_[v];
23dfcca431 2011-02-23        kinaba: 	}
23dfcca431 2011-02-23        kinaba: 	const T& id2v(int i) const { return id2v_[i]; }
23dfcca431 2011-02-23        kinaba: 	int size() const { return id2v_.size(); }
23dfcca431 2011-02-23        kinaba: };
23dfcca431 2011-02-23        kinaba: 
23dfcca431 2011-02-23        kinaba: template<typename Vert, typename Cost, typename Flow, int NV=256>
23dfcca431 2011-02-23        kinaba: class MinCostFlow
23dfcca431 2011-02-23        kinaba: {
23dfcca431 2011-02-23        kinaba: 	IdGen<Vert> idgen;
23dfcca431 2011-02-23        kinaba: 
23dfcca431 2011-02-23        kinaba: 	vector<int> G[NV];
23dfcca431 2011-02-23        kinaba: 	Flow F[NV][NV];
23dfcca431 2011-02-23        kinaba: 	Cost C[NV][NV];
23dfcca431 2011-02-23        kinaba: 
23dfcca431 2011-02-23        kinaba: public:
23dfcca431 2011-02-23        kinaba: 	void addEdge( Vert s_, Vert t_, Cost c, Flow f )
23dfcca431 2011-02-23        kinaba: 	{
23dfcca431 2011-02-23        kinaba: 		int s = idgen.v2id(s_), t = idgen.v2id(t_);
23dfcca431 2011-02-23        kinaba: 		G[s].push_back(t);
23dfcca431 2011-02-23        kinaba: 		G[t].push_back(s);
23dfcca431 2011-02-23        kinaba: 		C[s][t] = c;
23dfcca431 2011-02-23        kinaba: 		C[t][s] = -c;
23dfcca431 2011-02-23        kinaba: 		F[s][t] = f;
23dfcca431 2011-02-23        kinaba: 		F[t][s] = 0;
23dfcca431 2011-02-23        kinaba: 	}
23dfcca431 2011-02-23        kinaba: 
23dfcca431 2011-02-23        kinaba: 	pair<Cost, Flow> calc( Vert s_, Vert t_ )
23dfcca431 2011-02-23        kinaba: 	{
23dfcca431 2011-02-23        kinaba: 		const int N=idgen.size(), S=idgen.v2id(s_), T=idgen.v2id(t_);
524cc07867 2012-04-03        kinaba: 		static const Cost COST_INF = 1e+300; // !!EDIT HERE!!
524cc07867 2012-04-03        kinaba: 		static const Flow FLOW_INF = 0x7fffffff;
23dfcca431 2011-02-23        kinaba: 
23dfcca431 2011-02-23        kinaba: 		Cost total_cost = 0;
23dfcca431 2011-02-23        kinaba: 		Flow total_flow = 0;
524cc07867 2012-04-03        kinaba: 		vector<Cost> dist(N, 0); // Distance from S : initially unknown.
524cc07867 2012-04-03        kinaba: 		for(;;)
23dfcca431 2011-02-23        kinaba: 		{
524cc07867 2012-04-03        kinaba: 			// Dijkstra : find the "shortest path" from S to T wrt C[][].
524cc07867 2012-04-03        kinaba: 			//   C[][] can be <0 so we must be careful. Instead of computing the shortest path directly,
524cc07867 2012-04-03        kinaba: 			//   we compute the increase ("delta") from the shortest path in the previous iteration.
524cc07867 2012-04-03        kinaba: 			//   Since shortest path cannot decrease, delta is always >=0 when traversing edges.
524cc07867 2012-04-03        kinaba: 			//   Smallest delta implies smallest dist[T]+delta[T].
524cc07867 2012-04-03        kinaba: 			vector<Cost> delta(N, COST_INF); delta[S] = 0;
23dfcca431 2011-02-23        kinaba: 			vector<int>  prev(N, -1);
23dfcca431 2011-02-23        kinaba: 
524cc07867 2012-04-03        kinaba: 			typedef pair< Cost, pair<int, int> > cedge;
23dfcca431 2011-02-23        kinaba: 			priority_queue< cedge, vector<cedge>, greater<cedge> > Q;
524cc07867 2012-04-03        kinaba: 			Q.push( cedge(0, make_pair(S, S)) );
23dfcca431 2011-02-23        kinaba: 			while( !Q.empty() ) {
524cc07867 2012-04-03        kinaba: 				const cedge e = Q.top(); Q.pop();
524cc07867 2012-04-03        kinaba: 				const int u_prev = e.second.first;
524cc07867 2012-04-03        kinaba: 				const int u = e.second.second;
524cc07867 2012-04-03        kinaba: 				if( prev[u] >= 0 ) // visited
23dfcca431 2011-02-23        kinaba: 					continue;
524cc07867 2012-04-03        kinaba: 				prev[u] = u_prev;
23dfcca431 2011-02-23        kinaba: 
23dfcca431 2011-02-23        kinaba: 				for(int i=0; i<G[u].size(); ++i) {
524cc07867 2012-04-03        kinaba: 					const int  v = G[u][i];
524cc07867 2012-04-03        kinaba: 					const Cost v_delta = dist[u]+delta[u]+C[u][v] - dist[v];
524cc07867 2012-04-03        kinaba: 					if( F[u][v]>0 && delta[v]>v_delta )
524cc07867 2012-04-03        kinaba: 						Q.push( cedge(delta[v]=v_delta, make_pair(u,v)) );
23dfcca431 2011-02-23        kinaba: 				}
23dfcca431 2011-02-23        kinaba: 			}
23dfcca431 2011-02-23        kinaba: 
524cc07867 2012-04-03        kinaba: 			// If T is unreachable, finished.
23dfcca431 2011-02-23        kinaba: 			if( prev[T] < 0 )
524cc07867 2012-04-03        kinaba: 				break;
524cc07867 2012-04-03        kinaba: 
524cc07867 2012-04-03        kinaba: 			// Update the distance table.
524cc07867 2012-04-03        kinaba: 			for(int u=0; u<N; ++u)
524cc07867 2012-04-03        kinaba: 				if( delta[u] != COST_INF )
524cc07867 2012-04-03        kinaba: 					dist[u] += delta[u];
23dfcca431 2011-02-23        kinaba: 
524cc07867 2012-04-03        kinaba: 			// How much water can flow on the min-cost path?
524cc07867 2012-04-03        kinaba: 			Flow f = FLOW_INF;
23dfcca431 2011-02-23        kinaba: 			for(int u=T; u!=S; u=prev[u])
23dfcca431 2011-02-23        kinaba: 				f = min(f, F[prev[u]][u]);
23dfcca431 2011-02-23        kinaba: 
524cc07867 2012-04-03        kinaba: 			// Run the flow as much as possible
524cc07867 2012-04-03        kinaba: 			total_flow += f;
524cc07867 2012-04-03        kinaba: 			for(int u=T; u!=S; u=prev[u]) {
23dfcca431 2011-02-23        kinaba: 				total_cost    += f * C[prev[u]][u];
23dfcca431 2011-02-23        kinaba: 				F[prev[u]][u] -= f;
23dfcca431 2011-02-23        kinaba: 				F[u][prev[u]] += f;
23dfcca431 2011-02-23        kinaba: 			}
23dfcca431 2011-02-23        kinaba: 		}
23dfcca431 2011-02-23        kinaba: 		return make_pair(total_cost, total_flow);
23dfcca431 2011-02-23        kinaba: 	}
23dfcca431 2011-02-23        kinaba: };