#include <stdio.h> #include <vector> using std::vector; constexpr size_t SIZE_T_MAX = -1; int main(void) { size_t TC; scanf("%lu", &TC); while (TC--) { bool twins_pair = false; bool all_same = true; // Has only 2 and 1 nodes' degrees bool string_graph = true; bool good_string_graph = false; bool at_least_one_red = false; // 0 bool at_least_one_black = false; // 1 size_t n; scanf("%lu", &n); char *initial = new char[n+1]; char *desirable = new char[n+1]; scanf("%s %s", initial, desirable); size_t *node_degree = new size_t[n]{ }; vector<vector<size_t>> graph(n); // Makes sense only if string_graph size_t start_node = 0; size_t a, b; for (size_t i = 0; i < n-1; ++i) { scanf("%lu %lu", &a, &b); --a; --b; if (desirable[a] == desirable[b]) twins_pair = true; ++node_degree[a]; ++node_degree[b]; graph[a].push_back(b); graph[b].push_back(a); } for (size_t i = 0; i < n; ++i) { if (initial[i] != desirable[i]) all_same = false; if (node_degree[i] > 2) string_graph = false; if (node_degree[i] == 1) start_node = i; if (initial[i] == '0') at_least_one_red = true; if (initial[i] == '1') at_least_one_black = true; } if (string_graph && n >= 2) { bool *visited = new bool[n]{ }; size_t v = graph[start_node][0]; visited[start_node] = true; visited[v] = true; char cur_color_A = initial[start_node]; char cur_color_B = desirable[start_node]; size_t red_blocks_A = 0; size_t red_blocks_B = 0; size_t black_blocks_A = 0; size_t black_blocks_B = 0; while (true) { if (initial[v] != cur_color_A) { if (cur_color_A == '0') ++red_blocks_A; else ++black_blocks_A; cur_color_A = initial[v]; } if (desirable[v] != cur_color_B) { if (cur_color_B == '0') ++red_blocks_B; else ++black_blocks_B; cur_color_B = desirable[v]; } size_t w = SIZE_T_MAX; for (size_t i = 0; i < graph[v].size(); ++i) { if (visited[graph[v][i]] == false) { w = graph[v][i]; break; } } if (w == SIZE_T_MAX) break; else { visited[w] = true; v = w; } } if (cur_color_A == '0') ++red_blocks_A; else ++black_blocks_A; if (cur_color_B == '0') ++red_blocks_B; else ++black_blocks_B; good_string_graph = ( red_blocks_A == red_blocks_B && black_blocks_A == black_blocks_B && initial[start_node] == desirable[start_node] ) || ( red_blocks_A > red_blocks_B && black_blocks_A >= black_blocks_B ) || ( red_blocks_A >= red_blocks_B && black_blocks_A > black_blocks_B ); } if (all_same || ( !string_graph && twins_pair && at_least_one_red && at_least_one_black ) || ( string_graph && good_string_graph )) { printf("TAK\n"); } else { printf("NIE\n"); } } 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 | #include <stdio.h> #include <vector> using std::vector; constexpr size_t SIZE_T_MAX = -1; int main(void) { size_t TC; scanf("%lu", &TC); while (TC--) { bool twins_pair = false; bool all_same = true; // Has only 2 and 1 nodes' degrees bool string_graph = true; bool good_string_graph = false; bool at_least_one_red = false; // 0 bool at_least_one_black = false; // 1 size_t n; scanf("%lu", &n); char *initial = new char[n+1]; char *desirable = new char[n+1]; scanf("%s %s", initial, desirable); size_t *node_degree = new size_t[n]{ }; vector<vector<size_t>> graph(n); // Makes sense only if string_graph size_t start_node = 0; size_t a, b; for (size_t i = 0; i < n-1; ++i) { scanf("%lu %lu", &a, &b); --a; --b; if (desirable[a] == desirable[b]) twins_pair = true; ++node_degree[a]; ++node_degree[b]; graph[a].push_back(b); graph[b].push_back(a); } for (size_t i = 0; i < n; ++i) { if (initial[i] != desirable[i]) all_same = false; if (node_degree[i] > 2) string_graph = false; if (node_degree[i] == 1) start_node = i; if (initial[i] == '0') at_least_one_red = true; if (initial[i] == '1') at_least_one_black = true; } if (string_graph && n >= 2) { bool *visited = new bool[n]{ }; size_t v = graph[start_node][0]; visited[start_node] = true; visited[v] = true; char cur_color_A = initial[start_node]; char cur_color_B = desirable[start_node]; size_t red_blocks_A = 0; size_t red_blocks_B = 0; size_t black_blocks_A = 0; size_t black_blocks_B = 0; while (true) { if (initial[v] != cur_color_A) { if (cur_color_A == '0') ++red_blocks_A; else ++black_blocks_A; cur_color_A = initial[v]; } if (desirable[v] != cur_color_B) { if (cur_color_B == '0') ++red_blocks_B; else ++black_blocks_B; cur_color_B = desirable[v]; } size_t w = SIZE_T_MAX; for (size_t i = 0; i < graph[v].size(); ++i) { if (visited[graph[v][i]] == false) { w = graph[v][i]; break; } } if (w == SIZE_T_MAX) break; else { visited[w] = true; v = w; } } if (cur_color_A == '0') ++red_blocks_A; else ++black_blocks_A; if (cur_color_B == '0') ++red_blocks_B; else ++black_blocks_B; good_string_graph = ( red_blocks_A == red_blocks_B && black_blocks_A == black_blocks_B && initial[start_node] == desirable[start_node] ) || ( red_blocks_A > red_blocks_B && black_blocks_A >= black_blocks_B ) || ( red_blocks_A >= red_blocks_B && black_blocks_A > black_blocks_B ); } if (all_same || ( !string_graph && twins_pair && at_least_one_red && at_least_one_black ) || ( string_graph && good_string_graph )) { printf("TAK\n"); } else { printf("NIE\n"); } } return 0; } |