DELETED SRM/499-U/1A.cpp Index: SRM/499-U/1A.cpp ================================================================== --- SRM/499-U/1A.cpp +++ SRM/499-U/1A.cpp @@ -1,90 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; -typedef long long LL; -typedef complex CMP; - -class ColorfulRabbits { public: - int getMinimum(vector replies) - { - map m; - for(int i=0; i::iterator it=m.begin(); it!=m.end(); ++it) - { - int s = it->first + 1; - int n = it->second; - total += (n+s-1) / s * s; - } - return total; - } -}; - -// 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 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(_, ColorfulRabbits().getMinimum(replies));} -int main(){ - -CASE(0) - int replies_[] = { 1, 1, 2, 2 } -; - vector replies(replies_, replies_+sizeof(replies_)/sizeof(*replies_)); - int _ = 5; -END -CASE(1) - int replies_[] = { 0 } -; - vector replies(replies_, replies_+sizeof(replies_)/sizeof(*replies_)); - int _ = 1; -END -CASE(2) - int replies_[] = { 2, 2, 44, 2, 2, 2, 444, 2, 2 } -; - vector replies(replies_, replies_+sizeof(replies_)/sizeof(*replies_)); - int _ = 499; -END -CASE(3) - int replies_[] = {1}; - vector replies(replies_, replies_+sizeof(replies_)/sizeof(*replies_)); - int _ = 2; -END -CASE(4) - int replies_[] = {2}; - vector replies(replies_, replies_+sizeof(replies_)/sizeof(*replies_)); - int _ = 3; -END -CASE(5) - int replies_[] = {1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000}; - vector replies(replies_, replies_+sizeof(replies_)/sizeof(*replies_)); - int _ = -1; -END - -} -// END CUT HERE DELETED SRM/499-U/1B-U.cpp Index: SRM/499-U/1B-U.cpp ================================================================== --- SRM/499-U/1B-U.cpp +++ SRM/499-U/1B-U.cpp @@ -1,113 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; -typedef long long LL; -typedef complex CMP; - -class WhiteSpaceEditing { public: - int getMinimum(vector lines) - { - const int N = lines.size(); - const int V = *max_element(lines.begin(), lines.end()); - vector dp(V+1), dp_neo(V+1); - for(int v=0; v<=V; ++v) - dp[v] = abs(v - lines[N-1]); - for(int i=N-2; i>=0; --i) - { - int best = INT_MAX; - for(int v=lines[i]; v>=0; --v) { - best = min(best, dp[v]); - dp_neo[v] = abs(v - lines[i]) + best; - } - best = INT_MAX; - for(int v=lines[i]; v<=V; ++v) { - best = min(best, dp[v]); - dp_neo[v] = abs(v - lines[i]) + best; - } - dp.swap(dp_neo); - } - return dp[0] + N-1; - } -}; - -// 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 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(_, WhiteSpaceEditing().getMinimum(lines));} -int main(){ - -CASE(0) - int lines_[] = { 3, 2, 3 }; - vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); - int _ = 6; -END -CASE(1) - int lines_[] = { 0 }; - vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); - int _ = 0; -END -CASE(2) - int lines_[] = { 1, 2, 4 } -; - vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); - int _ = 6; -END -CASE(3) - int lines_[] = { 250, 105, 155, 205, 350 } -; - vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); - int _ = 499; -END -CASE(4) -int lines_[] = {0}; - vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); - int _ = 0; -END -CASE(5) -int lines_[] = {1}; - vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); - int _ = 1; -END -CASE(5) - int lines_[] = {10}; - vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); - int _ = 10; -END -CASE(5) - int lines_[] = {10,10}; - vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); - int _ = 11; -END -CASE(5) - int lines_[] = {1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000}; - vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); - int _ = 1000049; -END - -} -// END CUT HERE DELETED SRM/499-U/1C-U.cpp Index: SRM/499-U/1C-U.cpp ================================================================== --- SRM/499-U/1C-U.cpp +++ SRM/499-U/1C-U.cpp @@ -1,226 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; -typedef long long LL; -typedef complex CMP; - -template -class Graph -{ - map v2id_; - vector id2v_; -public: - vector< vector > G; - - int vert( const V& t ) - { - if( !v2id_.count(t) ) { v2id_[t] = G.size(); id2v_.push_back(t); G.resize(G.size()+1); } - return v2id_[t]; - } - void edge( const V& s_, const V& t_ ) - { - int s=vert(s_), t=vert(t_); - G[s].push_back(t); - } - const V& orig( int v ) - { - return id2v_[v]; - } -}; - -class StronglyConnectedComponent -{ -public: - StronglyConnectedComponent( const vector< vector >& G ) - : scc(), forest(), G(G), no(0), dfs_no(G.size()), dfs_lo(G.size()), scc_id(G.size()) - { - for(int v=0; v > scc; // scc[i] : the list of verts in the i-th component - vector< vector > forest; // the forest structure over sccs - -private: - const vector< vector >& G; - int no; - vector dfs_no; // Special: 0 : not visited yet - vector dfs_lo; // Special: INT_MAX : already classified into some scc !!!! not a good idea! - // rather use scc_id for that purpose (distinguishing assigned or not) - vector scc_id; - vector pending; - - void dfs(int v) - { - if( dfs_no[v] ) - return; - - dfs_no[v] = dfs_lo[v] = ++no; // visit v - for(int i=0; i dfs_lo:=INT_MAX - scc.push_back(pending), pending.clear(); - - // construct scc-forest (if needed) - scc_id[v] = scc.size()-1; - set children; - for(int i=0; i(children.begin(), children.end()) ); - } - } -}; - - -class ImpossibleGame { public: - static LL C(LL n, LL k) { - LL v = 1; - for(int i=1; i<=k; ++i) - v = v * (n+1-i) / i; - return v; - } - static LL weight(LL a, LL b, LL c, LL d) { - return C(a+b+c+d,a) * C(b+c+d,b) * C(c+d,c); - } - - long long getMinimum(int k, vector before, vector after) - { - vector< pair< vector, vector > > dif; - for(int i=0; i be(4), af(4); - for(int j=0; j > G; - - vector v(4); - for(v[0]=0; v[0]<=k; ++v[0]) - for(v[1]=0; v[0]+v[1]<=k; ++v[1]) - for(v[2]=0; v[0]+v[1]+v[2]<=k; ++v[2]) - for(v[3]=0; v[0]+v[1]+v[2]+v[3]<=k; ++v[3]) - { - G.vert(v); - for(int i=0; i u = v; - for(int k=0; k<4; ++k) - { - if( (u[k]-=dif[i].first[k]) < 0 ) - dame = true; - u[k] += dif[i].second[k]; - } - if( !dame ) - G.edge(v, u); - } - } - - StronglyConnectedComponent scc(G.G); - return 0; - } -}; - -// 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 long long& Expected, const long long& 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(_, ImpossibleGame().getMinimum(k, before, after));} -int main(){ - -CASE(0) - int k = 1; - string before_[] = { "A" } -; - vector before(before_, before_+sizeof(before_)/sizeof(*before_)); - string after_[] = { "B" } -; - vector after(after_, after_+sizeof(after_)/sizeof(*after_)); - long long _ = 2LL; -END -CASE(1) - int k = 2; - string before_[] = { "A", "A", "D" } -; - vector before(before_, before_+sizeof(before_)/sizeof(*before_)); - string after_[] = { "B", "C", "D" } -; - vector after(after_, after_+sizeof(after_)/sizeof(*after_)); - long long _ = 5LL; -END -CASE(2) - int k = 2; - string before_[] = { "B", "C", "D" } -; - vector before(before_, before_+sizeof(before_)/sizeof(*before_)); - string after_[] = { "C", "D", "B" } -; - vector after(after_, after_+sizeof(after_)/sizeof(*after_)); - long long _ = 9LL; -END -CASE(3) - int k = 6; - string before_[] = { "AABBC", "AAAADA", "AAACA", "CABAA", "AAAAAA", "BAAAA" } -; - vector before(before_, before_+sizeof(before_)/sizeof(*before_)); - string after_[] = { "AACCB", "DAAABC", "AAAAD", "ABCBA", "AABAAA", "AACAA" } -; - vector after(after_, after_+sizeof(after_)/sizeof(*after_)); - long long _ = 499LL; -END -/* -CASE(4) - int k = ; - string before_[] = ; - vector before(before_, before_+sizeof(before_)/sizeof(*before_)); - string after_[] = ; - vector after(after_, after_+sizeof(after_)/sizeof(*after_)); - long long _ = LL; -END -CASE(5) - int k = ; - string before_[] = ; - vector before(before_, before_+sizeof(before_)/sizeof(*before_)); - string after_[] = ; - vector after(after_, after_+sizeof(after_)/sizeof(*after_)); - long long _ = LL; -END -*/ -} -// END CUT HERE ADDED SRM/499/1A.cpp Index: SRM/499/1A.cpp ================================================================== --- SRM/499/1A.cpp +++ SRM/499/1A.cpp @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef complex CMP; + +class ColorfulRabbits { public: + int getMinimum(vector replies) + { + map m; + for(int i=0; i::iterator it=m.begin(); it!=m.end(); ++it) + { + int s = it->first + 1; + int n = it->second; + total += (n+s-1) / s * s; + } + return total; + } +}; + +// 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 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(_, ColorfulRabbits().getMinimum(replies));} +int main(){ + +CASE(0) + int replies_[] = { 1, 1, 2, 2 } +; + vector replies(replies_, replies_+sizeof(replies_)/sizeof(*replies_)); + int _ = 5; +END +CASE(1) + int replies_[] = { 0 } +; + vector replies(replies_, replies_+sizeof(replies_)/sizeof(*replies_)); + int _ = 1; +END +CASE(2) + int replies_[] = { 2, 2, 44, 2, 2, 2, 444, 2, 2 } +; + vector replies(replies_, replies_+sizeof(replies_)/sizeof(*replies_)); + int _ = 499; +END +CASE(3) + int replies_[] = {1}; + vector replies(replies_, replies_+sizeof(replies_)/sizeof(*replies_)); + int _ = 2; +END +CASE(4) + int replies_[] = {2}; + vector replies(replies_, replies_+sizeof(replies_)/sizeof(*replies_)); + int _ = 3; +END +CASE(5) + int replies_[] = {1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000}; + vector replies(replies_, replies_+sizeof(replies_)/sizeof(*replies_)); + int _ = -1; +END + +} +// END CUT HERE ADDED SRM/499/1B-U.cpp Index: SRM/499/1B-U.cpp ================================================================== --- SRM/499/1B-U.cpp +++ SRM/499/1B-U.cpp @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef complex CMP; + +class WhiteSpaceEditing { public: + int getMinimum(vector lines) + { + const int N = lines.size(); + const int V = *max_element(lines.begin(), lines.end()); + vector dp(V+1), dp_neo(V+1); + for(int v=0; v<=V; ++v) + dp[v] = abs(v - lines[N-1]); + for(int i=N-2; i>=0; --i) + { + int best = INT_MAX; + for(int v=lines[i]; v>=0; --v) { + best = min(best, dp[v]); + dp_neo[v] = abs(v - lines[i]) + best; + } + best = INT_MAX; + for(int v=lines[i]; v<=V; ++v) { + best = min(best, dp[v]); + dp_neo[v] = abs(v - lines[i]) + best; + } + dp.swap(dp_neo); + } + return dp[0] + N-1; + } +}; + +// 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 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(_, WhiteSpaceEditing().getMinimum(lines));} +int main(){ + +CASE(0) + int lines_[] = { 3, 2, 3 }; + vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); + int _ = 6; +END +CASE(1) + int lines_[] = { 0 }; + vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); + int _ = 0; +END +CASE(2) + int lines_[] = { 1, 2, 4 } +; + vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); + int _ = 6; +END +CASE(3) + int lines_[] = { 250, 105, 155, 205, 350 } +; + vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); + int _ = 499; +END +CASE(4) +int lines_[] = {0}; + vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); + int _ = 0; +END +CASE(5) +int lines_[] = {1}; + vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); + int _ = 1; +END +CASE(5) + int lines_[] = {10}; + vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); + int _ = 10; +END +CASE(5) + int lines_[] = {10,10}; + vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); + int _ = 11; +END +CASE(5) + int lines_[] = {1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000,1000000}; + vector lines(lines_, lines_+sizeof(lines_)/sizeof(*lines_)); + int _ = 1000049; +END + +} +// END CUT HERE ADDED SRM/499/1C.cpp Index: SRM/499/1C.cpp ================================================================== --- SRM/499/1C.cpp +++ SRM/499/1C.cpp @@ -0,0 +1,256 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef complex CMP; + +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 SCC +{ +public: + IdGen idgen; + vector< vector > G; + +public: + void addVert( Vert s_ ) + { + int s = idgen.v2id(s_); + if( s >= G.size() ) G.resize(s+1); + } + + void addEdge( Vert s_, Vert t_ ) + { + int s = idgen.v2id(s_), t = idgen.v2id(t_); + if( max(s,t) >= G.size() ) G.resize(max(s,t)+1); + G[s].push_back(t); + } + + void scc() + { + int N = G.size(); + dfs_no.assign(N, 0); + dfs_lo.assign(N, 0); + pending = stack(); + scc_id.assign(N, -1); + scc_list.clear(); + scc_children.clear(); + for(int v=0; v scc_id; // which scc does the vert belong to? + vector< vector > scc_list; // list of nodes in the scc + vector< vector > scc_children; // forest relationship of sccs + +private: + int no; + vector dfs_no; // 1-origin dfs-visit ID + vector dfs_lo; // the least ID in the vert's scc + stack pending; // current unclassigied verts + + void dfs(int v) + { + // visit v if not yet + if( dfs_no[v] ) + return; + dfs_no[v] = dfs_lo[v] = ++no; + pending.push(v); + + // visit children + for(int i=0; i scc; + for(;;) { + int w = pending.top(); pending.pop(); + scc.push_back(w); + scc_id[w] = scc_list.size(); + if( w == v ) break; + } + scc_list.push_back(scc); + + set children; + for(int j=0; j(children.begin(), children.end()) ); + } + } +}; + +class ImpossibleGame { public: + static LL C(LL n, LL k) { + LL v = 1; + for(int i=1; i<=k; ++i) + v = v * (n+1-i) / i; + return v; + } + + static LL weight(LL a, LL b, LL c, LL d) { + return C(a+b+c+d,a) * C(b+c+d,b) * C(c+d,c); + } + + long long getMinimum(int k, vector before, vector after) + { + vector< pair< vector, vector > > dif; + for(int i=0; i be(4), af(4); + for(int j=0; j > G; + + vector v(4); + for(v[0]=0; v[0]<=k; ++v[0]) + for(v[1]=0; v[0]+v[1]<=k; ++v[1]) + for(v[2]=0; v[0]+v[1]+v[2]<=k; ++v[2]) + { + v[3] = k - v[0] - v[1] - v[2]; + G.addVert(v); + for(int i=0; i u = v; + for(int k=0; k<4; ++k) + { + if( (u[k]-=dif[i].first[k]) < 0 ) + dame = true; + u[k] += dif[i].second[k]; + } + if( !dame ) + G.addEdge(v, u); + } + } + + G.scc(); + + LL ans = 0; + for(int v=0; v memo; + LL rec(int v, SCC< vector >& G) + { + if( memo.count(v) ) + return memo[v]; + LL mx = 0; + for(int i=0; i& str = G.idgen.id2v(G.scc_list[v][i]); + mx += weight(str[0], str[1], str[2], str[3]); + } + return memo[v] = mx; + } +}; + +// 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 long long& Expected, const long long& 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(_, ImpossibleGame().getMinimum(k, before, after));} +int main(){ + +CASE(0) + int k = 1; + string before_[] = { "A" }; + vector before(before_, before_+sizeof(before_)/sizeof(*before_)); + string after_[] = { "B" }; + vector after(after_, after_+sizeof(after_)/sizeof(*after_)); + long long _ = 2LL; +END +CASE(1) + int k = 2; + string before_[] = { "A", "A", "D" }; + vector before(before_, before_+sizeof(before_)/sizeof(*before_)); + string after_[] = { "B", "C", "D" }; + vector after(after_, after_+sizeof(after_)/sizeof(*after_)); + long long _ = 5LL; +END +CASE(2) + int k = 2; + string before_[] = { "B", "C", "D" }; + vector before(before_, before_+sizeof(before_)/sizeof(*before_)); + string after_[] = { "C", "D", "B" }; + vector after(after_, after_+sizeof(after_)/sizeof(*after_)); + long long _ = 9LL; +END +CASE(3) + int k = 6; + string before_[] = { "AABBC", "AAAADA", "AAACA", "CABAA", "AAAAAA", "BAAAA" }; + vector before(before_, before_+sizeof(before_)/sizeof(*before_)); + string after_[] = { "AACCB", "DAAABC", "AAAAD", "ABCBA", "AABAAA", "AACAA" }; + vector after(after_, after_+sizeof(after_)/sizeof(*after_)); + long long _ = 499LL; +END +CASE(4) + int k = 7; + string before_[] = {"BDBBB", "ACBBBBC", "BBBBC", "CCACCCB", "CC", "BBBBBBD", "BBDBBAB", "DBBCBB", "DBABABB", "BBBBABB", "BBBBB", "BBABB", "BBBBBDB", "ABDC", "BDBBDCB", "BBBBBAC", "BBBDBC", "BBBBBBA", "BBBBBBB", "BACCBB", "ABBDABB", "DC", "ABBDBB", "ACBCABB"}; + vector before(before_, before_+sizeof(before_)/sizeof(*before_)); + string after_[] = {"BADBC", "ACDBCBB", "BADCB", "BBBDBBC", "BD", "BBACCBD", "BBADBDB", "BBBBCC", "BBBCBBB", "BCBDCBD", "ABBBA", "DDBAB", "BCBDBDB", "BBCB", "BBCBBBB", "BABCBDB", "BBCCBD", "BBBBBCB", "DBCBADC", "BBBACA", "ABBABBC", "DB", "DBBCBB", "BBDBBBB"}; + vector after(after_, after_+sizeof(after_)/sizeof(*after_)); + long long _ = 7112LL; +END +/* +CASE(5) + int k = ; + string before_[] = ; + vector before(before_, before_+sizeof(before_)/sizeof(*before_)); + string after_[] = ; + vector after(after_, after_+sizeof(after_)/sizeof(*after_)); + long long _ = LL; +END +*/ +} +// END CUT HERE ADDED lib/graph/scc.cpp Index: lib/graph/scc.cpp ================================================================== --- lib/graph/scc.cpp +++ lib/graph/scc.cpp @@ -0,0 +1,104 @@ + +//------------------------------------------------------------- +// Strongly Connected Component of a Directed Graph +// O(E) +// +// Verified by +// - SRM 499 Div1 LV3 +// +// Using "Spagetthi Source"'s one path algorithm +//------------------------------------------------------------- + +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 SCC +{ + IdGen idgen; + vector< vector > G; + +public: + void addVert( Vert s_ ) + { + int s = idgen.v2id(s_); + if( s >= G.size() ) G.resize(s+1); + } + + void addEdge( Vert s_, Vert t_ ) + { + int s = idgen.v2id(s_), t = idgen.v2id(t_); + if( max(s,t) >= G.size() ) G.resize(max(s,t)+1); + G[s].push_back(t); + } + + void scc() + { + int N = G.size(); + dfs_no.assign(N, 0); + dfs_lo.assign(N, 0); + pending = stack(); + scc_id.assign(N, -1); + scc_list.clear(); + scc_children.clear(); + for(int v=0; v scc_id; // which scc does the vert belong to? + vector< vector > scc_list; // list of nodes in the scc + vector< vector > scc_children; // forest relationship of sccs + +private: + int no; + vector dfs_no; // 1-origin dfs-visit ID + vector dfs_lo; // the least ID in the vert's scc + stack pending; // current unclassigied verts + + void dfs(int v) + { + // visit v if not yet + if( dfs_no[v] ) + return; + dfs_no[v] = dfs_lo[v] = ++no; + pending.push(v); + + // visit children + for(int i=0; i scc; + for(;;) { + int w = pending.top(); pending.pop(); + scc.push_back(w); + scc_id[w] = scc_list.size(); + if( w == v ) break; + } + scc_list.push_back(scc); + + set children; + for(int j=0; j(children.begin(), children.end()) ); + } + } +};