File Annotation
Not logged in
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: //-------------------------------------------------------------
4fd800b3a8 2011-02-23        kinaba: // Gomory-Hu
4fd800b3a8 2011-02-23        kinaba: // All Pair Minimum Cuts for an Undirected Graph
4fd800b3a8 2011-02-23        kinaba: //   O(V^4)
4fd800b3a8 2011-02-23        kinaba: //
4fd800b3a8 2011-02-23        kinaba: // G : undirected (G[i].has(j) <==> G[j].has(i))
4fd800b3a8 2011-02-23        kinaba: // F : flow-capacity F[i][j] = F[j][i] = Capacity
4fd800b3a8 2011-02-23        kinaba: //
4fd800b3a8 2011-02-23        kinaba: // Verified by
4fd800b3a8 2011-02-23        kinaba: //   - CodeCraft 09 CUTS
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_graph GHF;
4fd800b3a8 2011-02-23        kinaba: void GomoryHu( graph& G, flow_graph F, flow_graph AllPairMinCut )
4fd800b3a8 2011-02-23        kinaba: {
4fd800b3a8 2011-02-23        kinaba: 	int N = G.size();
4fd800b3a8 2011-02-23        kinaba: 	vector<vert> parent(N, 0);
4fd800b3a8 2011-02-23        kinaba: 	vector<flow> weight(N, 0);
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: 	// construct the Gomory-Hu Tree
4fd800b3a8 2011-02-23        kinaba: 	for(vert s=1; s<N; ++s)
4fd800b3a8 2011-02-23        kinaba: 	{
4fd800b3a8 2011-02-23        kinaba: 		vert t = parent[s];
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: 		// mincut between s and t
4fd800b3a8 2011-02-23        kinaba: 		memcpy(GHF, F, sizeof(GHF));
4fd800b3a8 2011-02-23        kinaba: 		flow mincut = 0;
4fd800b3a8 2011-02-23        kinaba: 		for(;;) {
4fd800b3a8 2011-02-23        kinaba: 			// bfs
4fd800b3a8 2011-02-23        kinaba: 			vector<vert> prev(N, -1); prev[s]=s;
4fd800b3a8 2011-02-23        kinaba: 			queue<vert> Q; Q.push(s);
4fd800b3a8 2011-02-23        kinaba: 			while( !Q.empty() ) {
4fd800b3a8 2011-02-23        kinaba: 				vert v = Q.front(); Q.pop();
4fd800b3a8 2011-02-23        kinaba: 				for(int i=0; i<G[v].size(); ++i) {
4fd800b3a8 2011-02-23        kinaba: 					vert u = G[v][i];
4fd800b3a8 2011-02-23        kinaba: 					if( prev[u]==-1 && GHF[v][u] )
4fd800b3a8 2011-02-23        kinaba: 						prev[u]=v, Q.push(u);
4fd800b3a8 2011-02-23        kinaba: 				}
4fd800b3a8 2011-02-23        kinaba: 			}
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: 			if( prev[t] == -1 )
4fd800b3a8 2011-02-23        kinaba: 			{
4fd800b3a8 2011-02-23        kinaba: 				// done: separeted to {v|prev[v]!=-1} and {v|prev[v]==-1}
4fd800b3a8 2011-02-23        kinaba: 				// split t's children
4fd800b3a8 2011-02-23        kinaba: 				weight[s] = mincut;
4fd800b3a8 2011-02-23        kinaba: 				for(vert v=0; v<N; ++v)
4fd800b3a8 2011-02-23        kinaba: 					if( parent[v]==t && prev[v]!=-1 && v!=s )
4fd800b3a8 2011-02-23        kinaba: 						parent[v] = s;
4fd800b3a8 2011-02-23        kinaba: 				vert pt = parent[t];
4fd800b3a8 2011-02-23        kinaba: 				if( prev[pt]!=-1 )
4fd800b3a8 2011-02-23        kinaba: 					parent[s]=pt, parent[t]=s, weight[s]=weight[t], weight[t]=mincut;
4fd800b3a8 2011-02-23        kinaba: 				break;
4fd800b3a8 2011-02-23        kinaba: 			}
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: 			// flow...
4fd800b3a8 2011-02-23        kinaba: 			flow cur = 0x7fffffff;
4fd800b3a8 2011-02-23        kinaba: 			for(vert v=t; v!=s; v=prev[v])
4fd800b3a8 2011-02-23        kinaba: 				cur = min(cur, GHF[prev[v]][v]);
4fd800b3a8 2011-02-23        kinaba: 			for(vert v=t; v!=s; v=prev[v])
4fd800b3a8 2011-02-23        kinaba: 				GHF[prev[v]][v] -= cur, GHF[v][prev[v]] += cur;
4fd800b3a8 2011-02-23        kinaba: 			mincut += cur;
4fd800b3a8 2011-02-23        kinaba: 		}
4fd800b3a8 2011-02-23        kinaba: 	}
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: 	// AllPairMinCuts over the G-H tree
4fd800b3a8 2011-02-23        kinaba: 	for(vert s=0; s<N; ++s) {
4fd800b3a8 2011-02-23        kinaba: 		vector<vert> ps_s;
4fd800b3a8 2011-02-23        kinaba: 		for(vert v=s ;; v=parent[v])
4fd800b3a8 2011-02-23        kinaba: 			{ ps_s.push_back(v); if( v==parent[v] ) break; }
4fd800b3a8 2011-02-23        kinaba: 		reverse(ps_s.begin(), ps_s.end());
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: 		for(vert t=s+1; t<N; ++t) {
4fd800b3a8 2011-02-23        kinaba: 			vector<vert> ps_t;
4fd800b3a8 2011-02-23        kinaba: 			for(vert v=t ;; v=parent[v])
4fd800b3a8 2011-02-23        kinaba: 				{ ps_t.push_back(v); if( v==parent[v] ) break; }
4fd800b3a8 2011-02-23        kinaba: 			reverse(ps_t.begin(), ps_t.end());
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: 			vert ca;
4fd800b3a8 2011-02-23        kinaba: 			for(int i=0; i<ps_s.size() && i<ps_t.size() && ps_s[i]==ps_t[i]; ++i)
4fd800b3a8 2011-02-23        kinaba: 				ca = ps_s[i];
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: 			flow s_to_root = 0x7fffffff, t_to_root = 0x7fffffff;
4fd800b3a8 2011-02-23        kinaba: 			for(vert v=s; v!=ca; v=parent[v])
4fd800b3a8 2011-02-23        kinaba: 				s_to_root = min(s_to_root, weight[v]);
4fd800b3a8 2011-02-23        kinaba: 			for(vert v=t; v!=ca; v=parent[v])
4fd800b3a8 2011-02-23        kinaba: 				t_to_root = min(t_to_root, weight[v]);
4fd800b3a8 2011-02-23        kinaba: 			AllPairMinCut[s][t] = AllPairMinCut[t][s] = min(s_to_root, t_to_root);
4fd800b3a8 2011-02-23        kinaba: 		}
4fd800b3a8 2011-02-23        kinaba: 	}
4fd800b3a8 2011-02-23        kinaba: }