#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; } |
English