ADDED SRM/TCO12-3A-U/1A-U.cpp Index: SRM/TCO12-3A-U/1A-U.cpp ================================================================== --- SRM/TCO12-3A-U/1A-U.cpp +++ SRM/TCO12-3A-U/1A-U.cpp @@ -0,0 +1,140 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef long double LD; +typedef complex CMP; + +class ChromaticNumber { public: + int minColors(vector graph) + { + const int N = graph.size(); + + vector< vector > conn(N, vector(N, false)); + vector deg(N); + for(int i=0; i used(N, false); + for(int i=0; i ps(1, i); + for(int k=i+1; k +double start_time; string timer() + { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } +template ostream& operator<<(ostream& os, const vector& v) + { os << "{ "; + for(typename vector::const_iterator it=v.begin(); it!=v.end(); ++it) + os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } +void verify_case(const int& Expected, const int& Received) { + bool ok = (Expected == Received); + if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; + cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } +#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); +#define END verify_case(_, ChromaticNumber().minColors(graph));} +int main(){ + +CASE(0) + string graph_[] = {"N"}; + vector graph(graph_, graph_+sizeof(graph_)/sizeof(*graph_)); + int _ = 1; +END +CASE(1) + string graph_[] = {"NYY", + "YNN", + "YNN"}; + vector graph(graph_, graph_+sizeof(graph_)/sizeof(*graph_)); + int _ = 2; +END +CASE(2) + string graph_[] = {"NYNN", + "YNNN", + "NNNY", + "NNYN"}; + vector graph(graph_, graph_+sizeof(graph_)/sizeof(*graph_)); + int _ = 2; +END +CASE(3) + string graph_[] = {"NYNY", + "YNYY", + "NYNN", + "YYNN"}; + vector graph(graph_, graph_+sizeof(graph_)/sizeof(*graph_)); + int _ = 3; +END +CASE(4) + string graph_[] = {"NYYYYYYY", + "YNYYYYYY", + "YYNYYYYY", + "YYYNYYYY", + "YYYYNYYY", + "YYYYYNYY", + "YYYYYYNY", + "YYYYYYYN"}; + vector graph(graph_, graph_+sizeof(graph_)/sizeof(*graph_)); + int _ = 8; +END +/* +CASE(5) + string graph_[] = ; + vector graph(graph_, graph_+sizeof(graph_)/sizeof(*graph_)); + int _ = ; +END +CASE(6) + string graph_[] = ; + vector graph(graph_, graph_+sizeof(graph_)/sizeof(*graph_)); + int _ = ; +END +*/ +} +// END CUT HERE ADDED SRM/TCO12-3A-U/1B-U.cpp Index: SRM/TCO12-3A-U/1B-U.cpp ================================================================== --- SRM/TCO12-3A-U/1B-U.cpp +++ SRM/TCO12-3A-U/1B-U.cpp @@ -0,0 +1,262 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef long double LD; +typedef complex CMP; + + +//------------------------------------------------------------- +// Dinic's Algorithm +// O(V E) +// +// G : bidirectional (G[i].has(j) <==> G[j].has(i)) +// F : flow-capacity F[i][j] = Capacity, F[j][i] = 0 +// +// Verified by +// - SRM 399 Div1 LV3 +// - PKU 1459 +// - CodeCraft 09 CUTS +// - SRM 465 Div1 LV2 +// - SRM 543 Div1 LV3 +//------------------------------------------------------------- + +template +class IdGen +{ + map v2id_; + vector id2v_; +public: + int v2id(const T& v) { + if( !v2id_.count(v) ) { v2id_[v] = size(); id2v_.push_back(v); } + return v2id_[v]; + } + const T& id2v(int i) const { return id2v_[i]; } + int size() const { return id2v_.size(); } +}; + +template +class MaxFlow +{ + IdGen idgen; + vector G[NV]; + Flow F[NV][NV]; + +public: + void addEdge( Vert s_, Vert t_, Flow f ) + { + const int s = idgen.v2id(s_), t = idgen.v2id(t_); + G[s].push_back(t); + G[t].push_back(s); + F[s][t] = f; + F[t][s] = 0; + } + + Flow calc( Vert s_, Vert t_ ) + { + const int S = idgen.v2id(s_), D = idgen.v2id(t_); + for( Flow total=0 ;; ) { + // Do BFS and compute the level for each node. + int LV[NV] = {0}; + vector Q(1, S); + for(int lv=1; !Q.empty(); ++lv) { + vector Q2; + for(size_t i=0; i!=Q.size(); ++i) { + const vector& ne = G[Q[i]]; + for(size_t j=0; j!=ne.size(); ++j) + if( F[Q[i]][ne[j]] && !LV[ne[j]] && ne[j]!=S ) + LV[ne[j]]=lv, Q2.push_back(ne[j]); + } + Q.swap(Q2); + } + + // Destination is now unreachable. Done. + if( !LV[D] ) + return total; + + // Iterating DFS. + bool blocked[NV] = {}; + total += dinic_dfs( S, D, LV, 0x7fffffff, blocked ); + } + } + +private: + Flow dinic_dfs( int v, int D, int LV[], Flow flow_in, bool blocked[] ) + { + Flow flow_out = 0; + for(size_t i=0; i!=G[v].size(); ++i) { + int u = G[v][i]; + if( LV[v]+1==LV[u] && F[v][u] ) { + Flow f = min(flow_in-flow_out, F[v][u]); + if( u==D || !blocked[u] && (f=dinic_dfs(u,D,LV,f,blocked))>0 ) { + F[v][u] -= f; + F[u][v] += f; + flow_out += f; + if( flow_in == flow_out ) return flow_out; + } + } + } + blocked[v] = (flow_out==0); + return flow_out; + } +}; + +class FoxAndCake { public: + string ableToDivide(int W, int H, vector x, vector y) + { + vector< vector > M = compress(W, H, x, y); + H = M.size(); + W = M[0].size(); + + typedef pair< int, pair > Vert; + enum {IN, OUT, SPECIAL}; + Vert Src(SPECIAL, make_pair(0, 0)); + Vert Sink(SPECIAL, make_pair(1, 1)); + + MaxFlow G; + for(int y=0; y > compress(int W, int H, vector& x, vector& y) + { + for(int i=0; i<7; ++i) + --x[i], --y[i]; + + set sigx, sigy; + for(int i=0; i<7; ++i) + for(int d=-3; d<=+3; ++d) { + if(0<=x[i]+d && x[i]+d sx(sigx.begin(), sigx.end()); + vector sy(sigy.begin(), sigy.end()); + map inv_sx; for(int i=0; i inv_sy; for(int i=0; i > result(H, vector(W, ' ')); + for(int i=0; i<7; ++i) { + int xx = inv_sx[x[i]]; + int yy = inv_sy[y[i]]; + result[yy][xx] = (i==0?'#':i<4?'C':'S'); + } + return result; + } + +}; + +// BEGIN CUT HERE +#include +double start_time; string timer() + { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } +template ostream& operator<<(ostream& os, const vector& v) + { os << "{ "; + for(typename vector::const_iterator it=v.begin(); it!=v.end(); ++it) + os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } +void verify_case(const string& Expected, const string& Received) { + bool ok = (Expected == Received); + if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; + cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } +#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); +#define END verify_case(_, FoxAndCake().ableToDivide(n, m, x, y));} +int main(){ + +CASE(0) + int n = 2; + int m = 4; + int x_[] = {1,1,1,1,2,2,2}; + vector x(x_, x_+sizeof(x_)/sizeof(*x_)); + int y_[] = {1,2,3,4,2,3,4}; + vector y(y_, y_+sizeof(y_)/sizeof(*y_)); + string _ = "Yes"; +END +CASE(1) + int n = 2; + int m = 4; + int x_[] = {1,1,2,1,2,1,2}; + vector x(x_, x_+sizeof(x_)/sizeof(*x_)); + int y_[] = {1,2,2,3,3,4,4}; + vector y(y_, y_+sizeof(y_)/sizeof(*y_)); + string _ = "No"; +END +CASE(2) + int n = 6; + int m = 6; + int x_[] = {1,1,3,4,3,4,5}; + vector x(x_, x_+sizeof(x_)/sizeof(*x_)); + int y_[] = {2,6,4,5,5,4,2}; + vector y(y_, y_+sizeof(y_)/sizeof(*y_)); + string _ = "Yes"; +END +CASE(3) + int n = 999999999; + int m = 999999999; + int x_[] = {500000000,1,1,1,999999999,999999999,999999999}; + vector x(x_, x_+sizeof(x_)/sizeof(*x_)); + int y_[] = {500000000,1,2,3,999999997,999999998,999999999}; + vector y(y_, y_+sizeof(y_)/sizeof(*y_)); + string _ = "Yes"; +END +CASE(4) + int n = 1000000000; + int m = 1000000000; + int x_[] = {500000000,1,1,2,999999998,999999999,999999999}; + vector x(x_, x_+sizeof(x_)/sizeof(*x_)); + int y_[] = {500000000,1,2,1,999999999,999999998,999999999}; + vector y(y_, y_+sizeof(y_)/sizeof(*y_)); + string _ = "No"; +END +CASE(5) + int n = 7; + int m = 2; + int x_[] = {4,1,2,3,5,6,7}; + vector x(x_, x_+sizeof(x_)/sizeof(*x_)); + int y_[] = {2,1,2,2,2,2,1}; + vector y(y_, y_+sizeof(y_)/sizeof(*y_)); + string _ = "No"; +END +CASE(6) + int n = 7; + int m = 2; + int x_[] = {5,1,2,4,3,6,7}; + vector x(x_, x_+sizeof(x_)/sizeof(*x_)); + int y_[] = {1,1,1,1,1,1,1}; + vector y(y_, y_+sizeof(y_)/sizeof(*y_)); + string _ = "No"; +END +} +// END CUT HERE