4fd800b3a8 2011-02-23 kinaba: #include <iostream> 4fd800b3a8 2011-02-23 kinaba: #include <sstream> 4fd800b3a8 2011-02-23 kinaba: #include <iomanip> 4fd800b3a8 2011-02-23 kinaba: #include <vector> 4fd800b3a8 2011-02-23 kinaba: #include <string> 4fd800b3a8 2011-02-23 kinaba: #include <map> 4fd800b3a8 2011-02-23 kinaba: #include <set> 4fd800b3a8 2011-02-23 kinaba: #include <algorithm> 4fd800b3a8 2011-02-23 kinaba: #include <numeric> 4fd800b3a8 2011-02-23 kinaba: #include <iterator> 4fd800b3a8 2011-02-23 kinaba: #include <functional> 4fd800b3a8 2011-02-23 kinaba: #include <complex> 4fd800b3a8 2011-02-23 kinaba: #include <queue> 4fd800b3a8 2011-02-23 kinaba: #include <stack> 4fd800b3a8 2011-02-23 kinaba: #include <cmath> 4fd800b3a8 2011-02-23 kinaba: #include <cassert> 4fd800b3a8 2011-02-23 kinaba: #include <cstring> 4fd800b3a8 2011-02-23 kinaba: using namespace std; 4fd800b3a8 2011-02-23 kinaba: typedef long long LL; 4fd800b3a8 2011-02-23 kinaba: typedef complex<double> CMP; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: static const LL SHIFT = 1000000000LL; 4fd800b3a8 2011-02-23 kinaba: static const LL INF = 1000001LL; 4fd800b3a8 2011-02-23 kinaba: static const LL MAX = 1000000LL; 4fd800b3a8 2011-02-23 kinaba: static const int NV = 5002; 4fd800b3a8 2011-02-23 kinaba: typedef LL 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: typedef map< vert,map<vert,flow> > flow_graph; 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: } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: flow_graph F; 4fd800b3a8 2011-02-23 kinaba: class BarbarianInvasion { 4fd800b3a8 2011-02-23 kinaba: public: 4fd800b3a8 2011-02-23 kinaba: int minimalDetachment(vector <string> countryMap, vector <int> detachmentSize) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: int H = countryMap.size(); 4fd800b3a8 2011-02-23 kinaba: int W = countryMap[0].size(); 4fd800b3a8 2011-02-23 kinaba: vert OUT = 0, CAP = 1; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: graph G(H*W*2+2); 4fd800b3a8 2011-02-23 kinaba: flow_graph F; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: for(int y=0; y<H; ++y) 4fd800b3a8 2011-02-23 kinaba: for(int x=0; x<W; ++x) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: if( countryMap[y][x] == '-' ) 4fd800b3a8 2011-02-23 kinaba: continue; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: vert CUR_A = countryMap[y][x] == '*' ? CAP : (y*W+x)*2+2; // ==>A->B==> 4fd800b3a8 2011-02-23 kinaba: vert CUR_B = countryMap[y][x] == '*' ? CAP : (y*W+x)*2+3; 4fd800b3a8 2011-02-23 kinaba: if( countryMap[y][x] != '*' && countryMap[y][x] != '-' ) { 4fd800b3a8 2011-02-23 kinaba: G[CUR_A].push_back(CUR_B); 4fd800b3a8 2011-02-23 kinaba: G[CUR_B].push_back(CUR_A); 4fd800b3a8 2011-02-23 kinaba: F[CUR_A][CUR_B] = SHIFT + detachmentSize[countryMap[y][x]-'A']; 4fd800b3a8 2011-02-23 kinaba: F[CUR_B][CUR_A] = 0; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: int DY[] = {-1,+1,0,0}, DX[]={0,0,-1,+1}; 4fd800b3a8 2011-02-23 kinaba: for(int d=0; d<4; ++d) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: int dy = DY[d], dx = DX[d]; 4fd800b3a8 2011-02-23 kinaba: if( 0<=y+dy && y+dy<H && 0<=x+dx && x+dx<W ) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: if( countryMap[y+dy][x+dx] == '-' ) 4fd800b3a8 2011-02-23 kinaba: continue; 4fd800b3a8 2011-02-23 kinaba: if( countryMap[y+dy][x+dx] == '*' ) 4fd800b3a8 2011-02-23 kinaba: continue; 4fd800b3a8 2011-02-23 kinaba: vert ADJ_B = ((y+dy)*W+(x+dx))*2+3; 4fd800b3a8 2011-02-23 kinaba: G[ADJ_B].push_back(CUR_A); 4fd800b3a8 2011-02-23 kinaba: G[CUR_A].push_back(ADJ_B); 4fd800b3a8 2011-02-23 kinaba: F[ADJ_B][CUR_A] = SHIFT+INF; 4fd800b3a8 2011-02-23 kinaba: F[CUR_A][ADJ_B] = 0; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: else 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: G[OUT].push_back(CUR_A); 4fd800b3a8 2011-02-23 kinaba: G[CUR_A].push_back(OUT); 4fd800b3a8 2011-02-23 kinaba: F[OUT][CUR_A] = SHIFT+INF; 4fd800b3a8 2011-02-23 kinaba: F[CUR_A][OUT] = 0; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: flow mf = maxFlow(G, F, OUT, CAP); 4fd800b3a8 2011-02-23 kinaba: return mf%SHIFT; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: }; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: // BEGIN CUT HERE 4fd800b3a8 2011-02-23 kinaba: #include <ctime> 4fd800b3a8 2011-02-23 kinaba: double start_time;string timer() { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); } 4fd800b3a8 2011-02-23 kinaba: int verify_case(const int &Expected, const int &Received) { if (Expected == Received) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } return 0;} 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: template<int N> struct Case_ { Case_(){start_time=clock();} }; 4fd800b3a8 2011-02-23 kinaba: char Test_(...); 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<0>) { 4fd800b3a8 2011-02-23 kinaba: string countryMap_[] = {"ABA", 4fd800b3a8 2011-02-23 kinaba: "A*A", 4fd800b3a8 2011-02-23 kinaba: "AAA"}; 4fd800b3a8 2011-02-23 kinaba: vector <string> countryMap(countryMap_, countryMap_+sizeof(countryMap_)/sizeof(*countryMap_)); 4fd800b3a8 2011-02-23 kinaba: int detachmentSize_[] = {1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; 4fd800b3a8 2011-02-23 kinaba: vector <int> detachmentSize(detachmentSize_, detachmentSize_+sizeof(detachmentSize_)/sizeof(*detachmentSize_)); 4fd800b3a8 2011-02-23 kinaba: int RetVal = 5; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, BarbarianInvasion().minimalDetachment(countryMap, detachmentSize)); } 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<1>) { 4fd800b3a8 2011-02-23 kinaba: string countryMap_[] = {"CCCC", 4fd800b3a8 2011-02-23 kinaba: "-BAC", 4fd800b3a8 2011-02-23 kinaba: "-*AC", 4fd800b3a8 2011-02-23 kinaba: "--AC"}; 4fd800b3a8 2011-02-23 kinaba: vector <string> countryMap(countryMap_, countryMap_+sizeof(countryMap_)/sizeof(*countryMap_)); 4fd800b3a8 2011-02-23 kinaba: int detachmentSize_[] = {5,20,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; 4fd800b3a8 2011-02-23 kinaba: vector <int> detachmentSize(detachmentSize_, detachmentSize_+sizeof(detachmentSize_)/sizeof(*detachmentSize_)); 4fd800b3a8 2011-02-23 kinaba: int RetVal = 25; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, BarbarianInvasion().minimalDetachment(countryMap, detachmentSize)); } 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<2>) { 4fd800b3a8 2011-02-23 kinaba: string countryMap_[] = {"A----A", 4fd800b3a8 2011-02-23 kinaba: "-AAAA-", 4fd800b3a8 2011-02-23 kinaba: "-AA*A-", 4fd800b3a8 2011-02-23 kinaba: "-AAAA-", 4fd800b3a8 2011-02-23 kinaba: "A----A"}; 4fd800b3a8 2011-02-23 kinaba: vector <string> countryMap(countryMap_, countryMap_+sizeof(countryMap_)/sizeof(*countryMap_)); 4fd800b3a8 2011-02-23 kinaba: int detachmentSize_[] = {9,8,2,5,3,2,1,2,6,10,4,6,7,1,7,8,8,8,2,9,7,6,5,1,5,10}; 4fd800b3a8 2011-02-23 kinaba: vector <int> detachmentSize(detachmentSize_, detachmentSize_+sizeof(detachmentSize_)/sizeof(*detachmentSize_)); 4fd800b3a8 2011-02-23 kinaba: int RetVal = 0; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, BarbarianInvasion().minimalDetachment(countryMap, detachmentSize)); } 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<3>) { 4fd800b3a8 2011-02-23 kinaba: string countryMap_[] = {"-A-----", 4fd800b3a8 2011-02-23 kinaba: "-BCCC*-", 4fd800b3a8 2011-02-23 kinaba: "-A-----"}; 4fd800b3a8 2011-02-23 kinaba: vector <string> countryMap(countryMap_, countryMap_+sizeof(countryMap_)/sizeof(*countryMap_)); 4fd800b3a8 2011-02-23 kinaba: int detachmentSize_[] = {1,5,10,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; 4fd800b3a8 2011-02-23 kinaba: vector <int> detachmentSize(detachmentSize_, detachmentSize_+sizeof(detachmentSize_)/sizeof(*detachmentSize_)); 4fd800b3a8 2011-02-23 kinaba: int RetVal = 5; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, BarbarianInvasion().minimalDetachment(countryMap, detachmentSize)); } 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<4>) { 4fd800b3a8 2011-02-23 kinaba: string countryMap_[] = {"WANNABRUTEFORCEMEHUH", 4fd800b3a8 2011-02-23 kinaba: "ASUDQWNHIOCASFIUQISA", 4fd800b3a8 2011-02-23 kinaba: "UWQD-ASFFC-AJSQOOWE-", 4fd800b3a8 2011-02-23 kinaba: "-----*Y--AVSSFIUQISA", 4fd800b3a8 2011-02-23 kinaba: "UWQD-ASFFC-AJSQOOWE-", 4fd800b3a8 2011-02-23 kinaba: "JUFDIFD-CHBVISBOOWE-", 4fd800b3a8 2011-02-23 kinaba: "WANNABRUTEFORCEMEHUH"}; 4fd800b3a8 2011-02-23 kinaba: vector <string> countryMap(countryMap_, countryMap_+sizeof(countryMap_)/sizeof(*countryMap_)); 4fd800b3a8 2011-02-23 kinaba: int detachmentSize_[] = {87,78,20,43,30,12,9,18,57,93,32,60,64,9,69,74,74,78,12,81,63,57,48,8,44,95}; 4fd800b3a8 2011-02-23 kinaba: vector <int> detachmentSize(detachmentSize_, detachmentSize_+sizeof(detachmentSize_)/sizeof(*detachmentSize_)); 4fd800b3a8 2011-02-23 kinaba: int RetVal = 218; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, BarbarianInvasion().minimalDetachment(countryMap, detachmentSize)); } 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<5>) { 4fd800b3a8 2011-02-23 kinaba: string countryMap_[] = { 4fd800b3a8 2011-02-23 kinaba: "WOMP-PVE-LV-NB-J---E", 4fd800b3a8 2011-02-23 kinaba: "K--MKNWSOLFKK-JHP--W", 4fd800b3a8 2011-02-23 kinaba: "BE-K--MPP-YGZI-DMVKG", 4fd800b3a8 2011-02-23 kinaba: "JGWRXQ-UYEROYGC--SZR", 4fd800b3a8 2011-02-23 kinaba: "KFYN--CRX*N--JS-M-S-", 4fd800b3a8 2011-02-23 kinaba: "TBFGG-OL--D-DY--RR-A", 4fd800b3a8 2011-02-23 kinaba: "AMJT-NV--P--XF-YUSBM", 4fd800b3a8 2011-02-23 kinaba: "HJ-C--KHU-KDZHERUUHM", 4fd800b3a8 2011-02-23 kinaba: "-FGQZOI-A--ZIPB--QOT", 4fd800b3a8 2011-02-23 kinaba: "PNLI-RWYZG-MNV-SUNJD", 4fd800b3a8 2011-02-23 kinaba: "YJ-EJLD-H---K-HSVZF-", 4fd800b3a8 2011-02-23 kinaba: "LKPGZGF-IQ-ETYQJ-VAR", 4fd800b3a8 2011-02-23 kinaba: "UGS--V-BOUGG-SMO--Q-", 4fd800b3a8 2011-02-23 kinaba: "DFVWRHC-D-XES-MEQMCQ", 4fd800b3a8 2011-02-23 kinaba: "L-PUXR-C-HL-WX-NFJJR", 4fd800b3a8 2011-02-23 kinaba: "-A-JLUQX--VWPFENHJZ-", 4fd800b3a8 2011-02-23 kinaba: "HNG-NQAF-VVCUU-WU-HL"}; 4fd800b3a8 2011-02-23 kinaba: vector <string> countryMap(countryMap_, countryMap_+sizeof(countryMap_)/sizeof(*countryMap_)); 4fd800b3a8 2011-02-23 kinaba: int detachmentSize_[] = { 4fd800b3a8 2011-02-23 kinaba: 96882, 90320, 19358, 82732, 80637, //ABCDE 4fd800b3a8 2011-02-23 kinaba: 88638, 43236, 34294, 49732, 86156, //FGHIJ 4fd800b3a8 2011-02-23 kinaba: 1186, 84308, 49312, 92789, 49312, //KLMNO 4fd800b3a8 2011-02-23 kinaba: 14324, 27420, 32881, 73865, 91069, //PQRST 4fd800b3a8 2011-02-23 kinaba: 7266, 60052, 98451, 84652, 3991, 58948}; //UVWXYZ 4fd800b3a8 2011-02-23 kinaba: vector <int> detachmentSize(detachmentSize_, detachmentSize_+sizeof(detachmentSize_)/sizeof(*detachmentSize_)); 4fd800b3a8 2011-02-23 kinaba: int RetVal = 69753; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, BarbarianInvasion().minimalDetachment(countryMap, detachmentSize)); } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: template<int N> void Run_() { cerr << "Test Case #" << N << "..." << flush; Test_(Case_<N>()); Run_<sizeof(Test_(Case_<N+1>()))==1 ? -1 : N+1>(); } 4fd800b3a8 2011-02-23 kinaba: template<> void Run_<-1>() {} 4fd800b3a8 2011-02-23 kinaba: int main() { Run_<0>(); } 4fd800b3a8 2011-02-23 kinaba: // END CUT HERE 4fd800b3a8 2011-02-23 kinaba: