#include <cstdio>
#include <vector>
#include <set>
using namespace std;
#define FOR(i,a,b) for(int (i)=(int)(a); (i)!=(int)(b); ++(i))
struct Node {
char src, dst;
vector<Node*> adj;
};
int t, n;
char S[100005];
vector<Node> nodes;
bool solve() {
// Read input
scanf("%d", &n);
nodes.resize(n);
scanf("%s", S); FOR(i,0,n) nodes[i].src = S[i];
scanf("%s", S); FOR(i,0,n) nodes[i].dst = S[i];
FOR(i,0,n-1) {
int a, b;
scanf("%d %d", &a, &b); --a; --b;
nodes[a].adj.push_back(&nodes[b]);
nodes[b].adj.push_back(&nodes[a]);
}
// Analyse
Node *v1 = 0;
int max_d = 0;
bool changed = false;
bool dst_has_adj_with_one_color = false;
bool good_hub_exists = false;
bool src_0 = false, src_1 = false, dst_0 = false, dst_1 = false;
FOR(i,0,n) {
Node &node = nodes[i];
max_d = max(max_d, (int)(node.adj.size()));
if (node.adj.size() == 1 && v1 == 0) v1 = &node;
if (node.src != node.dst) changed = true;
if (node.src == '0') src_0 = true; else src_1 = true;
if (node.dst == '0') dst_0 = true; else dst_1 = true;
bool adj_0 = false, adj_1 = false;
FOR(j,0,node.adj.size()) {
Node &adj_node = *node.adj[j];
if (adj_node.dst == node.dst) dst_has_adj_with_one_color = true;
if (adj_node.dst == '0') adj_0 = true; else adj_1 = true;
}
if (node.adj.size() >= 3) {
if (adj_0 && adj_1) good_hub_exists = true;
else if (adj_0 && node.dst == '0') good_hub_exists = true;
else if (adj_1 && node.dst == '1') good_hub_exists = true;
}
}
// Case 1 - no changes
if (!changed) return true;
// Case 2 - dst has color which does not exist inside src
if (!src_0) return !dst_0;
if (!src_1) return !dst_1;
// Case 3 - dst has only one color which exists inside src
if (!dst_1) return src_0;
if (!dst_0) return src_1;
// Case 4 - tree is a path
if (max_d <= 2) {
vector<char> src_bin, dst_bin;
Node *prev = 0;
Node *node = v1;
while(true) {
if (src_bin.empty() || src_bin.back() != node->src) src_bin.push_back(node->src);
if (dst_bin.empty() || dst_bin.back() != node->dst) dst_bin.push_back(node->dst);
if (node->adj.size() == 1 && prev != 0) break;
Node *next = node->adj[0];
if (next == prev) next = node->adj[1];
prev = node;
node = next;
}
if (src_bin.size() > dst_bin.size()) return true;
if (src_bin.size() < dst_bin.size()) return false;
return src_bin[0] == dst_bin[0];
}
// Case 5 - There is a "hub" which can be used to modify exerything
if (good_hub_exists) return true;
if (dst_has_adj_with_one_color) return true;
return false;
}
int main() {
scanf("%d", &t);
while (t--) {
nodes.clear();
bool result = solve();
if (result) printf("TAK\n"); else printf("NIE\n");
}
}
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 | #include <cstdio> #include <vector> #include <set> using namespace std; #define FOR(i,a,b) for(int (i)=(int)(a); (i)!=(int)(b); ++(i)) struct Node { char src, dst; vector<Node*> adj; }; int t, n; char S[100005]; vector<Node> nodes; bool solve() { // Read input scanf("%d", &n); nodes.resize(n); scanf("%s", S); FOR(i,0,n) nodes[i].src = S[i]; scanf("%s", S); FOR(i,0,n) nodes[i].dst = S[i]; FOR(i,0,n-1) { int a, b; scanf("%d %d", &a, &b); --a; --b; nodes[a].adj.push_back(&nodes[b]); nodes[b].adj.push_back(&nodes[a]); } // Analyse Node *v1 = 0; int max_d = 0; bool changed = false; bool dst_has_adj_with_one_color = false; bool good_hub_exists = false; bool src_0 = false, src_1 = false, dst_0 = false, dst_1 = false; FOR(i,0,n) { Node &node = nodes[i]; max_d = max(max_d, (int)(node.adj.size())); if (node.adj.size() == 1 && v1 == 0) v1 = &node; if (node.src != node.dst) changed = true; if (node.src == '0') src_0 = true; else src_1 = true; if (node.dst == '0') dst_0 = true; else dst_1 = true; bool adj_0 = false, adj_1 = false; FOR(j,0,node.adj.size()) { Node &adj_node = *node.adj[j]; if (adj_node.dst == node.dst) dst_has_adj_with_one_color = true; if (adj_node.dst == '0') adj_0 = true; else adj_1 = true; } if (node.adj.size() >= 3) { if (adj_0 && adj_1) good_hub_exists = true; else if (adj_0 && node.dst == '0') good_hub_exists = true; else if (adj_1 && node.dst == '1') good_hub_exists = true; } } // Case 1 - no changes if (!changed) return true; // Case 2 - dst has color which does not exist inside src if (!src_0) return !dst_0; if (!src_1) return !dst_1; // Case 3 - dst has only one color which exists inside src if (!dst_1) return src_0; if (!dst_0) return src_1; // Case 4 - tree is a path if (max_d <= 2) { vector<char> src_bin, dst_bin; Node *prev = 0; Node *node = v1; while(true) { if (src_bin.empty() || src_bin.back() != node->src) src_bin.push_back(node->src); if (dst_bin.empty() || dst_bin.back() != node->dst) dst_bin.push_back(node->dst); if (node->adj.size() == 1 && prev != 0) break; Node *next = node->adj[0]; if (next == prev) next = node->adj[1]; prev = node; node = next; } if (src_bin.size() > dst_bin.size()) return true; if (src_bin.size() < dst_bin.size()) return false; return src_bin[0] == dst_bin[0]; } // Case 5 - There is a "hub" which can be used to modify exerything if (good_hub_exists) return true; if (dst_has_adj_with_one_color) return true; return false; } int main() { scanf("%d", &t); while (t--) { nodes.clear(); bool result = solve(); if (result) printf("TAK\n"); else printf("NIE\n"); } } |
English