ADDED SRM/682-U/1A.cpp Index: SRM/682-U/1A.cpp ================================================================== --- SRM/682-U/1A.cpp +++ SRM/682-U/1A.cpp @@ -0,0 +1,144 @@ +#include +#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; + +LL nei[2000][32]; + +class SmilesTheFriendshipUnicorn { public: + string hasFriendshipChain(int N, vector A, vector B) + { + return solve(N, A, B) ? "Yay!" : ":("; + } + + bool solve(int N, const vector& A, const vector& B) + { + vector> G(N); + for(int i=0; i>6] |= 1LL<<(u&0x3f); + for(int u: G[B[i]]) + nei[i][u>>6] |= 1LL<<(u&0x3f); + nei[i][A[i]>>6] &= ~(1LL<<(A[i]&0x3f)); + nei[i][B[i]>>6] &= ~(1LL<<(B[i]&0x3f)); + } + + for(int i=0; i +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(_, SmilesTheFriendshipUnicorn().hasFriendshipChain(N, A, B));} +int main(){ + +CASE(0) + int N = 5; + int A_[] = {0, 1, 2, 3}; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = {1, 2, 3, 4}; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + string _ = "Yay!"; +END +CASE(1) + int N = 5; + int A_[] = {0, 1, 2, 3, 1}; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = {1, 2, 3, 0, 4}; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + string _ = "Yay!"; +END +CASE(2) + int N = 6; + int A_[] = {0, 0, 0, 0, 0}; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = {1, 2, 3, 4, 5}; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + string _ = ":("; +END +CASE(3) + int N = 8; + int A_[] = {1, 3, 4, 3, 4, 3, 0, 2}; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = {7, 7, 7, 4, 6, 5, 4, 7}; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + string _ = "Yay!"; +END +CASE(4) + int N = 7; + int A_[] = {0, 1, 1, 5, 4, 5}; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = {5, 2, 3, 6, 1, 1}; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + string _ = ":("; +END +CASE(5) + int N = 42; + int A_[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41} +; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 0}; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + string _ = "Yay!"; +END +/* +CASE(6) + int N = ; + int A_[] = ; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = ; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + string _ = ; +END +CASE(7) + int N = ; + int A_[] = ; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = ; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + string _ = ; +END +*/ +} +// END CUT HERE ADDED SRM/682-U/1B.cpp Index: SRM/682-U/1B.cpp ================================================================== --- SRM/682-U/1B.cpp +++ SRM/682-U/1B.cpp @@ -0,0 +1,187 @@ +#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; + +set detect_cycle(int N, const vector>& G) +{ + vector stk; + set cycle; + function rec = [&](int pre, int v) { + stk.push_back(v); + for(int u: G[v]) if(u != pre) { + auto it = find(stk.begin(), stk.end(), u); + if(it == stk.end()) { + rec(v, u); + } else { + cycle = set(it, stk.end()); + } + } + stk.pop_back(); + }; + rec(-1, 0); + return cycle; +} + +vector> flatten(const vector>& GS) +{ + vector> G; + for(const auto& s: GS) + G.emplace_back(s.begin(), s.end()); + return G; +} + +class SuccessfulMerger { public: + int minimumMergers(vector road) + { + const int N = road.size(); + vector> Gs(N); + for(int i=0; i> G = flatten(Gs); + + set cy = detect_cycle(N, G); + if(cy.empty()) + return solve(N, G); + + int best = N-1; + set cyl = cy; + for(int survive: cyl) { + cy.erase(survive); + + map remap; + int XN = N - cy.size() + 1; + for(int v=0; v> XGs(XN); + for(int i=0; i> XG = flatten(XGs); + best = min(best, solve(XN, XG) + cy.size() - 1); + + cy.insert(survive); + } + return best; + } + + int solve(int N, const vector>& G) { + if(N <= 2) + return 0; + + int best = N-1; + for(int root=0; root>& G) + { + function non_leaf_cnt = [&](int pre, int v) { + if(G[v].size() == 1) + return 0; + int sum = 1; + for(int u: G[v]) if(u != pre) + sum += non_leaf_cnt(v, u); + return sum; + }; + + int total = 0; + for(int ch: G[root]) + total += non_leaf_cnt(root, ch); + 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(_, SuccessfulMerger().minimumMergers(road));} +int main(){ + +CASE(0) + int road_[] = {2, 2, 1, 1, 1}; + vector road(road_, road_+sizeof(road_)/sizeof(*road_)); + int _ = 1; +END +CASE(1) + int road_[] = {3, 4, 5, 4, 5, 3}; + vector road(road_, road_+sizeof(road_)/sizeof(*road_)); + int _ = 2; +END +CASE(2) + int road_[] = {1, 0, 1, 0, 0, 0, 1, 0, 1, 1}; + vector road(road_, road_+sizeof(road_)/sizeof(*road_)); + int _ = 1; +END +CASE(3) + int road_[] = {1, 2, 3, 0}; + vector road(road_, road_+sizeof(road_)/sizeof(*road_)); + int _ = 2; +END +CASE(4) + int road_[] = {31, 19, 0, 15, 30, 32, 15, 24, 0, 20, 40, 1, 22, 21, 39, 28, 0, 23, 15, 5, 19, 22, 6, 32, 8, 38, 35, 30, 4, 28, 32, 18, 18, 9, 22, 41, 20, 18, 6, 25, 41, 34, 4}; + vector road(road_, road_+sizeof(road_)/sizeof(*road_)); + int _ = 25; +END +CASE(5) + int road_[] = {1, 0}; + vector road(road_, road_+sizeof(road_)/sizeof(*road_)); + int _ = 0; +END +/* +CASE(6) + int road_[] = ; + vector road(road_, road_+sizeof(road_)/sizeof(*road_)); + int _ = ; +END +CASE(7) + int road_[] = ; + vector road(road_, road_+sizeof(road_)/sizeof(*road_)); + int _ = ; +END +*/ +} +// END CUT HERE