d948683958 2012-10-10 kinaba: #include <iostream> d948683958 2012-10-10 kinaba: #include <sstream> d948683958 2012-10-10 kinaba: #include <iomanip> d948683958 2012-10-10 kinaba: #include <vector> d948683958 2012-10-10 kinaba: #include <string> d948683958 2012-10-10 kinaba: #include <map> d948683958 2012-10-10 kinaba: #include <set> d948683958 2012-10-10 kinaba: #include <algorithm> d948683958 2012-10-10 kinaba: #include <numeric> d948683958 2012-10-10 kinaba: #include <iterator> d948683958 2012-10-10 kinaba: #include <functional> d948683958 2012-10-10 kinaba: #include <complex> d948683958 2012-10-10 kinaba: #include <queue> d948683958 2012-10-10 kinaba: #include <stack> d948683958 2012-10-10 kinaba: #include <cmath> d948683958 2012-10-10 kinaba: #include <cassert> d948683958 2012-10-10 kinaba: using namespace std; d948683958 2012-10-10 kinaba: typedef long long LL; d948683958 2012-10-10 kinaba: typedef long double LD; d948683958 2012-10-10 kinaba: typedef complex<LD> CMP; d948683958 2012-10-10 kinaba: d948683958 2012-10-10 kinaba: template<typename T> d948683958 2012-10-10 kinaba: class IdGen d948683958 2012-10-10 kinaba: { d948683958 2012-10-10 kinaba: map<T, int> v2id_; d948683958 2012-10-10 kinaba: vector<T> id2v_; d948683958 2012-10-10 kinaba: public: d948683958 2012-10-10 kinaba: int v2id(const T& v) { d948683958 2012-10-10 kinaba: if( !v2id_.count(v) ) { v2id_[v] = size(); id2v_.push_back(v); } d948683958 2012-10-10 kinaba: return v2id_[v]; d948683958 2012-10-10 kinaba: } d948683958 2012-10-10 kinaba: const T& id2v(int i) const { return id2v_[i]; } d948683958 2012-10-10 kinaba: int size() const { return id2v_.size(); } d948683958 2012-10-10 kinaba: }; d948683958 2012-10-10 kinaba: d948683958 2012-10-10 kinaba: template<typename Vert, typename Flow, int NV=2502> d948683958 2012-10-10 kinaba: class MaxFlow d948683958 2012-10-10 kinaba: { d948683958 2012-10-10 kinaba: IdGen<Vert> idgen; d948683958 2012-10-10 kinaba: vector<int> G[NV]; d948683958 2012-10-10 kinaba: Flow F[NV][NV]; d948683958 2012-10-10 kinaba: d948683958 2012-10-10 kinaba: public: d948683958 2012-10-10 kinaba: void addEdge( Vert s_, Vert t_, Flow f ) d948683958 2012-10-10 kinaba: { d948683958 2012-10-10 kinaba: const int s = idgen.v2id(s_), t = idgen.v2id(t_); d948683958 2012-10-10 kinaba: G[s].push_back(t); d948683958 2012-10-10 kinaba: G[t].push_back(s); d948683958 2012-10-10 kinaba: F[s][t] = f; d948683958 2012-10-10 kinaba: F[t][s] = 0; d948683958 2012-10-10 kinaba: } d948683958 2012-10-10 kinaba: d948683958 2012-10-10 kinaba: Flow calc( Vert s_, Vert t_ ) d948683958 2012-10-10 kinaba: { d948683958 2012-10-10 kinaba: const int S = idgen.v2id(s_), D = idgen.v2id(t_); d948683958 2012-10-10 kinaba: for( Flow total=0 ;; ) { d948683958 2012-10-10 kinaba: // Do BFS and compute the level for each node. d948683958 2012-10-10 kinaba: int LV[NV] = {0}; d948683958 2012-10-10 kinaba: vector<int> Q(1, S); d948683958 2012-10-10 kinaba: for(int lv=1; !Q.empty(); ++lv) { d948683958 2012-10-10 kinaba: vector<int> Q2; d948683958 2012-10-10 kinaba: for(size_t i=0; i!=Q.size(); ++i) { d948683958 2012-10-10 kinaba: const vector<int>& ne = G[Q[i]]; d948683958 2012-10-10 kinaba: for(size_t j=0; j!=ne.size(); ++j) d948683958 2012-10-10 kinaba: if( F[Q[i]][ne[j]] && !LV[ne[j]] && ne[j]!=S ) d948683958 2012-10-10 kinaba: LV[ne[j]]=lv, Q2.push_back(ne[j]); d948683958 2012-10-10 kinaba: } d948683958 2012-10-10 kinaba: Q.swap(Q2); d948683958 2012-10-10 kinaba: } d948683958 2012-10-10 kinaba: d948683958 2012-10-10 kinaba: // Destination is now unreachable. Done. d948683958 2012-10-10 kinaba: if( !LV[D] ) d948683958 2012-10-10 kinaba: return total; d948683958 2012-10-10 kinaba: d948683958 2012-10-10 kinaba: // Iterating DFS. d948683958 2012-10-10 kinaba: bool blocked[NV] = {}; d948683958 2012-10-10 kinaba: total += dinic_dfs( S, D, LV, 0x7fffffff, blocked ); d948683958 2012-10-10 kinaba: } d948683958 2012-10-10 kinaba: } d948683958 2012-10-10 kinaba: d948683958 2012-10-10 kinaba: private: d948683958 2012-10-10 kinaba: Flow dinic_dfs( int v, int D, int LV[], Flow flow_in, bool blocked[] ) d948683958 2012-10-10 kinaba: { d948683958 2012-10-10 kinaba: Flow flow_out = 0; d948683958 2012-10-10 kinaba: for(size_t i=0; i!=G[v].size(); ++i) { d948683958 2012-10-10 kinaba: int u = G[v][i]; d948683958 2012-10-10 kinaba: if( LV[v]+1==LV[u] && F[v][u] ) { d948683958 2012-10-10 kinaba: Flow f = min(flow_in-flow_out, F[v][u]); d948683958 2012-10-10 kinaba: if( u==D || !blocked[u] && (f=dinic_dfs(u,D,LV,f,blocked))>0 ) { d948683958 2012-10-10 kinaba: F[v][u] -= f; d948683958 2012-10-10 kinaba: F[u][v] += f; d948683958 2012-10-10 kinaba: flow_out += f; d948683958 2012-10-10 kinaba: if( flow_in == flow_out ) return flow_out; d948683958 2012-10-10 kinaba: } d948683958 2012-10-10 kinaba: } d948683958 2012-10-10 kinaba: } d948683958 2012-10-10 kinaba: blocked[v] = (flow_out==0); d948683958 2012-10-10 kinaba: return flow_out; d948683958 2012-10-10 kinaba: } d948683958 2012-10-10 kinaba: }; d948683958 2012-10-10 kinaba: d948683958 2012-10-10 kinaba: class OldBridges { public: d948683958 2012-10-10 kinaba: string isPossible(vector <string> bridges, int a1, int a2, int an, int b1, int b2, int bn) d948683958 2012-10-10 kinaba: { d948683958 2012-10-10 kinaba: typedef pair<int,int> Vert; d948683958 2012-10-10 kinaba: enum {SRC, SINK, VERT, E1, E2}; d948683958 2012-10-10 kinaba: static const int INF = 99999999; d948683958 2012-10-10 kinaba: MaxFlow<Vert, int>* mf = new MaxFlow<Vert,int>; d948683958 2012-10-10 kinaba: d948683958 2012-10-10 kinaba: mf->addEdge(Vert(SRC,0), Vert(VERT,a1), 2*an); d948683958 2012-10-10 kinaba: mf->addEdge(Vert(VERT,a2), Vert(SINK,0), 2*an); d948683958 2012-10-10 kinaba: mf->addEdge(Vert(SRC,0), Vert(VERT,b1), 2*bn); d948683958 2012-10-10 kinaba: mf->addEdge(Vert(VERT,b2), Vert(SINK,0), 2*bn); d948683958 2012-10-10 kinaba: d948683958 2012-10-10 kinaba: int N = bridges.size(); d948683958 2012-10-10 kinaba: for(int a=0; a<N; ++a) d948683958 2012-10-10 kinaba: for(int b=a+1; b<N; ++b) d948683958 2012-10-10 kinaba: if(bridges[a][b] == 'N') { d948683958 2012-10-10 kinaba: mf->addEdge(Vert(VERT,a), Vert(VERT,b), INF); d948683958 2012-10-10 kinaba: mf->addEdge(Vert(VERT,b), Vert(VERT,a), INF); d948683958 2012-10-10 kinaba: } else if(bridges[a][b] == 'O') { d948683958 2012-10-10 kinaba: Vert e1 = Vert(E1, a*N+b); d948683958 2012-10-10 kinaba: Vert e2 = Vert(E2, a*N+b); d948683958 2012-10-10 kinaba: mf->addEdge(Vert(VERT,a), e1, 2); d948683958 2012-10-10 kinaba: mf->addEdge(Vert(VERT,b), e1, 2); d948683958 2012-10-10 kinaba: mf->addEdge(e1, e2, 2); d948683958 2012-10-10 kinaba: mf->addEdge(e2, Vert(VERT,a), 2); d948683958 2012-10-10 kinaba: mf->addEdge(e2, Vert(VERT,b), 2); d948683958 2012-10-10 kinaba: } d948683958 2012-10-10 kinaba: d948683958 2012-10-10 kinaba: int flow = mf->calc(Vert(SRC,0), Vert(SINK,0)); d948683958 2012-10-10 kinaba: delete mf; d948683958 2012-10-10 kinaba: return flow==(an+an+bn+bn) ? "Yes" : "No"; d948683958 2012-10-10 kinaba: } d948683958 2012-10-10 kinaba: }; d948683958 2012-10-10 kinaba: d948683958 2012-10-10 kinaba: // BEGIN CUT HERE d948683958 2012-10-10 kinaba: #include <ctime> d948683958 2012-10-10 kinaba: double start_time; string timer() d948683958 2012-10-10 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } d948683958 2012-10-10 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) d948683958 2012-10-10 kinaba: { os << "{ "; d948683958 2012-10-10 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) d948683958 2012-10-10 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } d948683958 2012-10-10 kinaba: void verify_case(const string& Expected, const string& Received) { d948683958 2012-10-10 kinaba: bool ok = (Expected == Received); d948683958 2012-10-10 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; d948683958 2012-10-10 kinaba: cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } d948683958 2012-10-10 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); d948683958 2012-10-10 kinaba: #define END verify_case(_, OldBridges().isPossible(bridges, a1, a2, an, b1, b2, bn));} d948683958 2012-10-10 kinaba: int main(){ d948683958 2012-10-10 kinaba: d948683958 2012-10-10 kinaba: CASE(0) d948683958 2012-10-10 kinaba: string bridges_[] = {"XOXX","OXOX","XOXO","XXOX"}; d948683958 2012-10-10 kinaba: vector <string> bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); d948683958 2012-10-10 kinaba: int a1 = 0; d948683958 2012-10-10 kinaba: int a2 = 1; d948683958 2012-10-10 kinaba: int an = 1; d948683958 2012-10-10 kinaba: int b1 = 2; d948683958 2012-10-10 kinaba: int b2 = 3; d948683958 2012-10-10 kinaba: int bn = 1; d948683958 2012-10-10 kinaba: string _ = "Yes"; d948683958 2012-10-10 kinaba: END d948683958 2012-10-10 kinaba: CASE(1) d948683958 2012-10-10 kinaba: string bridges_[] = {"XOXX","OXOX","XOXO","XXOX"}; d948683958 2012-10-10 kinaba: vector <string> bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); d948683958 2012-10-10 kinaba: int a1 = 0; d948683958 2012-10-10 kinaba: int a2 = 2; d948683958 2012-10-10 kinaba: int an = 1; d948683958 2012-10-10 kinaba: int b1 = 1; d948683958 2012-10-10 kinaba: int b2 = 3; d948683958 2012-10-10 kinaba: int bn = 1; d948683958 2012-10-10 kinaba: string _ = "No"; d948683958 2012-10-10 kinaba: END d948683958 2012-10-10 kinaba: CASE(2) d948683958 2012-10-10 kinaba: string bridges_[] = {"XOXO","OXOX","XOXO","OXOX"}; d948683958 2012-10-10 kinaba: vector <string> bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); d948683958 2012-10-10 kinaba: int a1 = 0; d948683958 2012-10-10 kinaba: int a2 = 2; d948683958 2012-10-10 kinaba: int an = 1; d948683958 2012-10-10 kinaba: int b1 = 1; d948683958 2012-10-10 kinaba: int b2 = 3; d948683958 2012-10-10 kinaba: int bn = 1; d948683958 2012-10-10 kinaba: string _ = "Yes"; d948683958 2012-10-10 kinaba: END d948683958 2012-10-10 kinaba: CASE(3) d948683958 2012-10-10 kinaba: string bridges_[] = {"XNXO","NXOX","XOXO","OXOX"}; d948683958 2012-10-10 kinaba: vector <string> bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); d948683958 2012-10-10 kinaba: int a1 = 0; d948683958 2012-10-10 kinaba: int a2 = 2; d948683958 2012-10-10 kinaba: int an = 1; d948683958 2012-10-10 kinaba: int b1 = 1; d948683958 2012-10-10 kinaba: int b2 = 3; d948683958 2012-10-10 kinaba: int bn = 2; d948683958 2012-10-10 kinaba: string _ = "No"; d948683958 2012-10-10 kinaba: END d948683958 2012-10-10 kinaba: CASE(4) d948683958 2012-10-10 kinaba: string bridges_[] = {"XOXOO","OXOXO","XOXOO","OXOXO","OOOOX"}; d948683958 2012-10-10 kinaba: vector <string> bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); d948683958 2012-10-10 kinaba: int a1 = 0; d948683958 2012-10-10 kinaba: int a2 = 2; d948683958 2012-10-10 kinaba: int an = 2; d948683958 2012-10-10 kinaba: int b1 = 1; d948683958 2012-10-10 kinaba: int b2 = 3; d948683958 2012-10-10 kinaba: int bn = 2; d948683958 2012-10-10 kinaba: string _ = "Yes"; d948683958 2012-10-10 kinaba: END d948683958 2012-10-10 kinaba: CASE(5) d948683958 2012-10-10 kinaba: string bridges_[] = {"XOOOX","OXOOX","OOXOX","OOOXN","XXXNX"}; d948683958 2012-10-10 kinaba: vector <string> bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); d948683958 2012-10-10 kinaba: int a1 = 0; d948683958 2012-10-10 kinaba: int a2 = 4; d948683958 2012-10-10 kinaba: int an = 3; d948683958 2012-10-10 kinaba: int b1 = 1; d948683958 2012-10-10 kinaba: int b2 = 2; d948683958 2012-10-10 kinaba: int bn = 2; d948683958 2012-10-10 kinaba: string _ = "No"; d948683958 2012-10-10 kinaba: END d948683958 2012-10-10 kinaba: /* d948683958 2012-10-10 kinaba: CASE(6) d948683958 2012-10-10 kinaba: string bridges_[] = ; d948683958 2012-10-10 kinaba: vector <string> bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); d948683958 2012-10-10 kinaba: int a1 = ; d948683958 2012-10-10 kinaba: int a2 = ; d948683958 2012-10-10 kinaba: int an = ; d948683958 2012-10-10 kinaba: int b1 = ; d948683958 2012-10-10 kinaba: int b2 = ; d948683958 2012-10-10 kinaba: int bn = ; d948683958 2012-10-10 kinaba: string _ = ; d948683958 2012-10-10 kinaba: END d948683958 2012-10-10 kinaba: CASE(7) d948683958 2012-10-10 kinaba: string bridges_[] = ; d948683958 2012-10-10 kinaba: vector <string> bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); d948683958 2012-10-10 kinaba: int a1 = ; d948683958 2012-10-10 kinaba: int a2 = ; d948683958 2012-10-10 kinaba: int an = ; d948683958 2012-10-10 kinaba: int b1 = ; d948683958 2012-10-10 kinaba: int b2 = ; d948683958 2012-10-10 kinaba: int bn = ; d948683958 2012-10-10 kinaba: string _ = ; d948683958 2012-10-10 kinaba: END d948683958 2012-10-10 kinaba: */ d948683958 2012-10-10 kinaba: } d948683958 2012-10-10 kinaba: // END CUT HERE