2827f87024 2014-01-21 kinaba: #include <iostream> 2827f87024 2014-01-21 kinaba: #include <sstream> 2827f87024 2014-01-21 kinaba: #include <iomanip> 2827f87024 2014-01-21 kinaba: #include <vector> 2827f87024 2014-01-21 kinaba: #include <string> 2827f87024 2014-01-21 kinaba: #include <map> 2827f87024 2014-01-21 kinaba: #include <set> 2827f87024 2014-01-21 kinaba: #include <algorithm> 2827f87024 2014-01-21 kinaba: #include <numeric> 2827f87024 2014-01-21 kinaba: #include <iterator> 2827f87024 2014-01-21 kinaba: #include <functional> 2827f87024 2014-01-21 kinaba: #include <complex> 2827f87024 2014-01-21 kinaba: #include <queue> 2827f87024 2014-01-21 kinaba: #include <stack> 2827f87024 2014-01-21 kinaba: #include <cmath> 2827f87024 2014-01-21 kinaba: #include <cassert> 2827f87024 2014-01-21 kinaba: #include <tuple> 2827f87024 2014-01-21 kinaba: using namespace std; 2827f87024 2014-01-21 kinaba: typedef long long LL; 2827f87024 2014-01-21 kinaba: typedef complex<double> CMP; 2827f87024 2014-01-21 kinaba: 2827f87024 2014-01-21 kinaba: template<typename T> 2827f87024 2014-01-21 kinaba: struct DP2 2827f87024 2014-01-21 kinaba: { 2827f87024 2014-01-21 kinaba: const int N1, N2; 2827f87024 2014-01-21 kinaba: vector<T> data; 2827f87024 2014-01-21 kinaba: DP2(int N1, int N2, const T& t = T()) 2827f87024 2014-01-21 kinaba: : N1(N1), N2(N2), data(N1*N2, t) { assert(data.size()*sizeof(T)<(1<<28)); } 2827f87024 2014-01-21 kinaba: T& operator()(int i1, int i2) 2827f87024 2014-01-21 kinaba: { return data[ (i1*N2)+i2 ]; } 2827f87024 2014-01-21 kinaba: void swap(DP2& rhs) 2827f87024 2014-01-21 kinaba: { data.swap(rhs.data); } 2827f87024 2014-01-21 kinaba: }; 2827f87024 2014-01-21 kinaba: 2827f87024 2014-01-21 kinaba: static const int INF = 0x3fffffff; 2827f87024 2014-01-21 kinaba: class FoxConnection { public: 2827f87024 2014-01-21 kinaba: int minimalDistance(vector <int> A, vector <int> B, string haveFox) 2827f87024 2014-01-21 kinaba: { 2827f87024 2014-01-21 kinaba: int N = haveFox.size(); 2827f87024 2014-01-21 kinaba: vector<vector<int>> G(N); 2827f87024 2014-01-21 kinaba: for(int i=0; i<A.size(); ++i) { 2827f87024 2014-01-21 kinaba: int a = A[i] - 1; 2827f87024 2014-01-21 kinaba: int b = B[i] - 1; 2827f87024 2014-01-21 kinaba: G[a].push_back(b); 2827f87024 2014-01-21 kinaba: G[b].push_back(a); 2827f87024 2014-01-21 kinaba: } 2827f87024 2014-01-21 kinaba: 2827f87024 2014-01-21 kinaba: int best = INF; 2827f87024 2014-01-21 kinaba: memo.resize(N+1, vector<vector<int>>(N)); 2827f87024 2014-01-21 kinaba: ts_memo.resize(N+1, vector<int>(N, INF)); 2827f87024 2014-01-21 kinaba: for(int root=0; root<N; ++root) { 2827f87024 2014-01-21 kinaba: const vector<int>& L = rec(-1, root, G, haveFox); 2827f87024 2014-01-21 kinaba: best = min(best, L[0]); 2827f87024 2014-01-21 kinaba: } 2827f87024 2014-01-21 kinaba: return best==INF ? 0 : best; 2827f87024 2014-01-21 kinaba: } 2827f87024 2014-01-21 kinaba: 2827f87024 2014-01-21 kinaba: vector<vector<int>> ts_memo; 2827f87024 2014-01-21 kinaba: int treeSize(int prev, int v, const vector<vector<int>>& G, const string& haveFox) 2827f87024 2014-01-21 kinaba: { 2827f87024 2014-01-21 kinaba: if(ts_memo[prev+1][v] != INF) 2827f87024 2014-01-21 kinaba: return ts_memo[prev+1][v]; 2827f87024 2014-01-21 kinaba: 2827f87024 2014-01-21 kinaba: int ts = (haveFox[v]=='Y'); 2827f87024 2014-01-21 kinaba: for(int u : G[v]) if(u != prev) 2827f87024 2014-01-21 kinaba: ts += treeSize(v, u, G, haveFox); 2827f87024 2014-01-21 kinaba: return ts_memo[prev+1][v] = ts; 2827f87024 2014-01-21 kinaba: } 2827f87024 2014-01-21 kinaba: 2827f87024 2014-01-21 kinaba: vector<vector<vector<int>>> memo; 2827f87024 2014-01-21 kinaba: const vector<int>& rec(int prev, int v, const vector<vector<int>>& G, const string& haveFox) 2827f87024 2014-01-21 kinaba: { 2827f87024 2014-01-21 kinaba: if(!memo[prev+1][v].empty()) 2827f87024 2014-01-21 kinaba: return memo[prev+1][v]; 2827f87024 2014-01-21 kinaba: int N = G.size(); 2827f87024 2014-01-21 kinaba: 2827f87024 2014-01-21 kinaba: vector<const vector<int>*> children; 2827f87024 2014-01-21 kinaba: for(int u : G[v]) if(u != prev) 2827f87024 2014-01-21 kinaba: children.push_back(&rec(v,u,G,haveFox)); 2827f87024 2014-01-21 kinaba: int Z = children.size(); 2827f87024 2014-01-21 kinaba: 2827f87024 2014-01-21 kinaba: DP2<int> dp(Z+1, N, INF); 2827f87024 2014-01-21 kinaba: dp(0,0) = 0; 2827f87024 2014-01-21 kinaba: for(int i=0; i<Z; ++i) 2827f87024 2014-01-21 kinaba: { 2827f87024 2014-01-21 kinaba: const vector<int>& ch = *children[i]; 2827f87024 2014-01-21 kinaba: for(int t=0; t<N; ++t) 2827f87024 2014-01-21 kinaba: for(int w=0; w<N; ++w) 2827f87024 2014-01-21 kinaba: if(t+w<N) 2827f87024 2014-01-21 kinaba: dp(i+1, t+w) = min(dp(i+1, t+w), dp(i,t)+ch[w]); 2827f87024 2014-01-21 kinaba: } 2827f87024 2014-01-21 kinaba: 2827f87024 2014-01-21 kinaba: const bool Y = (haveFox[v]=='Y'); 2827f87024 2014-01-21 kinaba: vector<int>& L = memo[prev+1][v]; 2827f87024 2014-01-21 kinaba: L.resize(N, INF); 2827f87024 2014-01-21 kinaba: 2827f87024 2014-01-21 kinaba: const int TS = treeSize(prev, v, G, haveFox); 2827f87024 2014-01-21 kinaba: for(int i=0; i<N; ++i) 2827f87024 2014-01-21 kinaba: { 2827f87024 2014-01-21 kinaba: if(i == TS) 2827f87024 2014-01-21 kinaba: L[i] = min(INF, TS + (Y ? dp(Z,TS-1) : dp(Z,TS))); 2827f87024 2014-01-21 kinaba: else 2827f87024 2014-01-21 kinaba: L[i] = min(INF, i + (Y ? dp(Z,i) : i+1<N ? dp(Z,i+1) : INF)); 2827f87024 2014-01-21 kinaba: } 2827f87024 2014-01-21 kinaba: return L; 2827f87024 2014-01-21 kinaba: } 2827f87024 2014-01-21 kinaba: }; 2827f87024 2014-01-21 kinaba: 2827f87024 2014-01-21 kinaba: // BEGIN CUT HERE 2827f87024 2014-01-21 kinaba: #include <ctime> 2827f87024 2014-01-21 kinaba: double start_time; string timer() 2827f87024 2014-01-21 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } 2827f87024 2014-01-21 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) 2827f87024 2014-01-21 kinaba: { os << "{ "; 2827f87024 2014-01-21 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) 2827f87024 2014-01-21 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } 2827f87024 2014-01-21 kinaba: void verify_case(const int& Expected, const int& Received) { 2827f87024 2014-01-21 kinaba: bool ok = (Expected == Received); 2827f87024 2014-01-21 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; 2827f87024 2014-01-21 kinaba: cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } 2827f87024 2014-01-21 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); 2827f87024 2014-01-21 kinaba: #define END verify_case(_, FoxConnection().minimalDistance(A, B, haveFox));} 2827f87024 2014-01-21 kinaba: int main(){ 2827f87024 2014-01-21 kinaba: 2827f87024 2014-01-21 kinaba: CASE(0) 2827f87024 2014-01-21 kinaba: int A_[] = {1,2,3}; 2827f87024 2014-01-21 kinaba: vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_)); 2827f87024 2014-01-21 kinaba: int B_[] = {2,3,4}; 2827f87024 2014-01-21 kinaba: vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_)); 2827f87024 2014-01-21 kinaba: string haveFox = "YNNY"; 2827f87024 2014-01-21 kinaba: int _ = 2; 2827f87024 2014-01-21 kinaba: END 2827f87024 2014-01-21 kinaba: CASE(1) 2827f87024 2014-01-21 kinaba: int A_[] = {1,1,1,1}; 2827f87024 2014-01-21 kinaba: vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_)); 2827f87024 2014-01-21 kinaba: int B_[] = {2,3,4,5}; 2827f87024 2014-01-21 kinaba: vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_)); 2827f87024 2014-01-21 kinaba: string haveFox = "NYYYY"; 2827f87024 2014-01-21 kinaba: int _ = 1; 2827f87024 2014-01-21 kinaba: END 2827f87024 2014-01-21 kinaba: CASE(2) 2827f87024 2014-01-21 kinaba: int A_[] = {1,3,4,5,4}; 2827f87024 2014-01-21 kinaba: vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_)); 2827f87024 2014-01-21 kinaba: int B_[] = {2,2,2,4,6}; 2827f87024 2014-01-21 kinaba: vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_)); 2827f87024 2014-01-21 kinaba: string haveFox = "YNYNYY"; 2827f87024 2014-01-21 kinaba: int _ = 2; 2827f87024 2014-01-21 kinaba: END 2827f87024 2014-01-21 kinaba: CASE(3) 2827f87024 2014-01-21 kinaba: int A_[] = {1,2,3,4,5,6,7,8,9}; 2827f87024 2014-01-21 kinaba: vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_)); 2827f87024 2014-01-21 kinaba: int B_[] = {2,3,4,5,6,7,8,9,10}; 2827f87024 2014-01-21 kinaba: vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_)); 2827f87024 2014-01-21 kinaba: string haveFox = "YNNNYNYNNY"; 2827f87024 2014-01-21 kinaba: int _ = 7; 2827f87024 2014-01-21 kinaba: END 2827f87024 2014-01-21 kinaba: CASE(4) 2827f87024 2014-01-21 kinaba: int A_[] = {1,2,3,4,3,6,8,7}; 2827f87024 2014-01-21 kinaba: vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_)); 2827f87024 2014-01-21 kinaba: int B_[] = {2,3,4,5,6,8,9,6}; 2827f87024 2014-01-21 kinaba: vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_)); 2827f87024 2014-01-21 kinaba: string haveFox = "YNNYYNYYY"; 2827f87024 2014-01-21 kinaba: int _ = 3; 2827f87024 2014-01-21 kinaba: END 2827f87024 2014-01-21 kinaba: CASE(5) 2827f87024 2014-01-21 kinaba: int A_[] = {1}; 2827f87024 2014-01-21 kinaba: vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_)); 2827f87024 2014-01-21 kinaba: int B_[] = {2}; 2827f87024 2014-01-21 kinaba: vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_)); 2827f87024 2014-01-21 kinaba: string haveFox = "NY"; 2827f87024 2014-01-21 kinaba: int _ = 0; 2827f87024 2014-01-21 kinaba: END 2827f87024 2014-01-21 kinaba: CASE(6) 2827f87024 2014-01-21 kinaba: int A_[] = {1}; 2827f87024 2014-01-21 kinaba: vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_)); 2827f87024 2014-01-21 kinaba: int B_[] = {2}; 2827f87024 2014-01-21 kinaba: vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_)); 2827f87024 2014-01-21 kinaba: string haveFox = "NN"; 2827f87024 2014-01-21 kinaba: int _ = 0; 2827f87024 2014-01-21 kinaba: END 2827f87024 2014-01-21 kinaba: /* 2827f87024 2014-01-21 kinaba: CASE(7) 2827f87024 2014-01-21 kinaba: int A_[] = ; 2827f87024 2014-01-21 kinaba: vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_)); 2827f87024 2014-01-21 kinaba: int B_[] = ; 2827f87024 2014-01-21 kinaba: vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_)); 2827f87024 2014-01-21 kinaba: string haveFox = ; 2827f87024 2014-01-21 kinaba: int _ = ; 2827f87024 2014-01-21 kinaba: END 2827f87024 2014-01-21 kinaba: CASE(8) 2827f87024 2014-01-21 kinaba: int A_[] = ; 2827f87024 2014-01-21 kinaba: vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_)); 2827f87024 2014-01-21 kinaba: int B_[] = ; 2827f87024 2014-01-21 kinaba: vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_)); 2827f87024 2014-01-21 kinaba: string haveFox = ; 2827f87024 2014-01-21 kinaba: int _ = ; 2827f87024 2014-01-21 kinaba: END 2827f87024 2014-01-21 kinaba: */ 2827f87024 2014-01-21 kinaba: } 2827f87024 2014-01-21 kinaba: // END CUT HERE