#include <iostream> #include <vector> using namespace std; #define DEBUG 0 #define MAXN 1000001 int z,n; string color_start, color_end; vector<int> v[MAXN], colors_path_start, colors_path_end; void path_colors_start(int vertex, int parent){ colors_path_start.push_back(color_start[vertex] - '0'); for (int child: v[vertex]){ if (child != parent){ path_colors_start(child, vertex); } } } void path_colors_end(int vertex, int parent){ colors_path_end.push_back(color_end[vertex] - '0'); for (int child: v[vertex]){ if (child != parent){ path_colors_end(child, vertex); } } } bool possible(){ if (DEBUG){ cout << "Check possible " << n << endl; } if (color_start == color_end) return true; // CHECK IF REQUIRED COLORS ARE PRESENT int start_reds=0, end_reds=0; for (int i=0; i<n; ++i){ start_reds += (color_start[i] == '0'); end_reds += (color_end[i] == '0'); } if (start_reds == 0 && end_reds > 0) return false; if (n == start_reds && n > end_reds) return false; // CHECK GRAPH IS SINGLE PATH int max_vertex_degree = 0, vertex_leaf=0; for (int i=0; i<n; ++i){ if (v[i].size() > max_vertex_degree){ max_vertex_degree = v[i].size(); } if (v[i].size() == 1){ vertex_leaf = i; } } if (max_vertex_degree == 2){ path_colors_start(vertex_leaf, -1); path_colors_end(vertex_leaf, -1); if (DEBUG){ cout << "Path @ start: "; for (int p: colors_path_start){ cout << p << ' '; } cout << endl << "Path @ end: "; for (int p: colors_path_end){ cout << p << ' '; } cout << endl; } // Path @ start: 0 1 0 1 0 // Path @ end: 1 0 1 1 1 int start_i=0, end_j=0; while (start_i<n && end_j<n){ if (colors_path_start[start_i] != colors_path_end[end_j]){ start_i++; if (DEBUG) cout << "Going next i on start to number: " << start_i << endl; } else { if (DEBUG) cout << "Trying to grow current color: (" << start_i << ',' << end_j << ")"; int color = colors_path_start[start_i]; for (; colors_path_start[start_i] == color && start_i<n; start_i++); for (; colors_path_end[end_j] == color && end_j<n; end_j++); if (DEBUG) cout << " to numbers after 1 (" << start_i << ',' << end_j << ")" << endl; } } colors_path_start.clear(); colors_path_end.clear(); return (end_j == n && start_i<=n); // R - B - R - B - R // B - B - B - R - B // OK } // CHECK NEIGHBOURING VERTICES ARE OF THE SAME COLOR bool all_alternating_colors = true; for (int vertex=0; vertex < n; ++vertex){ for (int child: v[vertex]){ if (color_end[vertex] == color_end[child]){ all_alternating_colors = false; } } } return !all_alternating_colors; } int main() { scanf("%d", &z); while(z--){ scanf("%d ", &n); cin >> color_start >> color_end; for (int i=1; i<n; ++i){ int x,y; scanf("%d%d", &x, &y); v[x-1].push_back(y-1); v[y-1].push_back(x-1); } cout << ((possible())? "TAK" : "NIE") << endl; if (DEBUG) cout << endl << endl << endl; for (int i=0; i<n; ++i){ v[i].clear(); } } return 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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | #include <iostream> #include <vector> using namespace std; #define DEBUG 0 #define MAXN 1000001 int z,n; string color_start, color_end; vector<int> v[MAXN], colors_path_start, colors_path_end; void path_colors_start(int vertex, int parent){ colors_path_start.push_back(color_start[vertex] - '0'); for (int child: v[vertex]){ if (child != parent){ path_colors_start(child, vertex); } } } void path_colors_end(int vertex, int parent){ colors_path_end.push_back(color_end[vertex] - '0'); for (int child: v[vertex]){ if (child != parent){ path_colors_end(child, vertex); } } } bool possible(){ if (DEBUG){ cout << "Check possible " << n << endl; } if (color_start == color_end) return true; // CHECK IF REQUIRED COLORS ARE PRESENT int start_reds=0, end_reds=0; for (int i=0; i<n; ++i){ start_reds += (color_start[i] == '0'); end_reds += (color_end[i] == '0'); } if (start_reds == 0 && end_reds > 0) return false; if (n == start_reds && n > end_reds) return false; // CHECK GRAPH IS SINGLE PATH int max_vertex_degree = 0, vertex_leaf=0; for (int i=0; i<n; ++i){ if (v[i].size() > max_vertex_degree){ max_vertex_degree = v[i].size(); } if (v[i].size() == 1){ vertex_leaf = i; } } if (max_vertex_degree == 2){ path_colors_start(vertex_leaf, -1); path_colors_end(vertex_leaf, -1); if (DEBUG){ cout << "Path @ start: "; for (int p: colors_path_start){ cout << p << ' '; } cout << endl << "Path @ end: "; for (int p: colors_path_end){ cout << p << ' '; } cout << endl; } // Path @ start: 0 1 0 1 0 // Path @ end: 1 0 1 1 1 int start_i=0, end_j=0; while (start_i<n && end_j<n){ if (colors_path_start[start_i] != colors_path_end[end_j]){ start_i++; if (DEBUG) cout << "Going next i on start to number: " << start_i << endl; } else { if (DEBUG) cout << "Trying to grow current color: (" << start_i << ',' << end_j << ")"; int color = colors_path_start[start_i]; for (; colors_path_start[start_i] == color && start_i<n; start_i++); for (; colors_path_end[end_j] == color && end_j<n; end_j++); if (DEBUG) cout << " to numbers after 1 (" << start_i << ',' << end_j << ")" << endl; } } colors_path_start.clear(); colors_path_end.clear(); return (end_j == n && start_i<=n); // R - B - R - B - R // B - B - B - R - B // OK } // CHECK NEIGHBOURING VERTICES ARE OF THE SAME COLOR bool all_alternating_colors = true; for (int vertex=0; vertex < n; ++vertex){ for (int child: v[vertex]){ if (color_end[vertex] == color_end[child]){ all_alternating_colors = false; } } } return !all_alternating_colors; } int main() { scanf("%d", &z); while(z--){ scanf("%d ", &n); cin >> color_start >> color_end; for (int i=1; i<n; ++i){ int x,y; scanf("%d%d", &x, &y); v[x-1].push_back(y-1); v[y-1].push_back(x-1); } cout << ((possible())? "TAK" : "NIE") << endl; if (DEBUG) cout << endl << endl << endl; for (int i=0; i<n; ++i){ v[i].clear(); } } return 0; } |