#include "bits/stdc++.h" // Tomasz Nowak using namespace std; // University of Warsaw using LL = long long; #define FOR(i, l, r) for(int i = (l); i <= (r); ++i) #define REP(i, n) FOR(i, 0, (n) - 1) #define ssize(x) int(x.size()) template<class A, class B> auto& operator<<(ostream &o, pair<A, B> p) { return o << '(' << p.first << ", " << p.second << ')'; } template<class T> auto operator<<(ostream &o, T x) -> decltype(x.end(), o) { o << '{'; int i = 0; for(auto e : x) o << (", ")+2*!i++ << e; return o << '}'; } #ifdef DEBUG #define debug(x...) cerr << "[" #x "]: ", [](auto... $) {((cerr << $ << "; "), ...); }(x), cerr << '\n' #else #define debug(...) {} #endif int main() { cin.tie(0)->sync_with_stdio(0); int t; cin >> t; while(t --> 0) { int n; cin >> n; string from, to; cin >> from >> to; vector<vector<int>> graph(n); REP(edge, n - 1) { int v, u; cin >> v >> u; --v, --u; graph[v].emplace_back(u); graph[u].emplace_back(v); } debug(graph); auto get_ans = [&] { bool from_has_0 = *min_element(from.begin(), from.end()) == '0'; bool from_has_1 = *max_element(from.begin(), from.end()) == '1'; bool to_has_0 = *min_element(to.begin(), to.end()) == '0'; bool to_has_1 = *max_element(to.begin(), to.end()) == '1'; debug(from_has_0, from_has_1, to_has_0, to_has_1); if(to_has_0 and to_has_1 and (not from_has_0 or not from_has_1)) return false; if(from_has_0 and from_has_1 and (not to_has_0 or not to_has_1)) return true; if(not to_has_0 and not from_has_0) return true; if(not to_has_1 and not from_has_1) return true; if(not from_has_1 and to_has_1) return false; if(not from_has_0 and to_has_0) return false; assert(to_has_0 and to_has_1 and from_has_0 and from_has_1); bool has_splitpoint_vertex = false; REP(v, n) { int cnt0 = 0, cnt1 = 0; for(int u : graph[v]) ++(to[u] == '1' ? cnt1 : cnt0); if(cnt0 > 0 and cnt1 > 0 and cnt0 + cnt1 >= 3) has_splitpoint_vertex = true; } if(has_splitpoint_vertex) return true; bool has_deg_geq3 = false; REP(v, n) if(ssize(graph[v]) >= 3) has_deg_geq3 = true; if(has_deg_geq3) { bool is_bipartite = true; REP(v, n) for(int u : graph[v]) if(to[v] == to[u]) is_bipartite = false; if(from != to and is_bipartite) return false; else return true; } else { int first = -1; REP(v, n) if(ssize(graph[v]) == 1) first = v; assert(first != -1); vector<bool> vis(n); vector<int> order = {first}; while(ssize(order) != n) { int v = order.back(); vis[v] = true; for(int u : graph[v]) if(not vis[u]) order.emplace_back(u); } debug(order); int cnt_from_0_to_1 = 0, cnt_from_1_to_0 = 0; int cnt_to_0_to_1 = 0, cnt_to_1_to_0 = 0; REP(i, n - 1) { int v = order[i]; int u = order[i + 1]; debug(v, u); cnt_from_0_to_1 += bool(from[v] == '0' and from[u] == '1'); cnt_from_1_to_0 += bool(from[v] == '1' and from[u] == '0'); cnt_to_0_to_1 += bool(to[v] == '0' and to[u] == '1'); cnt_to_1_to_0 += bool(to[v] == '1' and to[u] == '0'); } debug(cnt_from_0_to_1, cnt_from_1_to_0, cnt_to_0_to_1, cnt_to_1_to_0); if(cnt_to_1_to_0 > cnt_from_1_to_0 or cnt_to_0_to_1 > cnt_from_0_to_1 or (cnt_to_1_to_0 == cnt_from_1_to_0 and cnt_to_0_to_1 == cnt_from_0_to_1 and from[order[0]] != to[order[0]])) return false; else return true; } }; cout << (get_ans() ? "TAK" : "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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | #include "bits/stdc++.h" // Tomasz Nowak using namespace std; // University of Warsaw using LL = long long; #define FOR(i, l, r) for(int i = (l); i <= (r); ++i) #define REP(i, n) FOR(i, 0, (n) - 1) #define ssize(x) int(x.size()) template<class A, class B> auto& operator<<(ostream &o, pair<A, B> p) { return o << '(' << p.first << ", " << p.second << ')'; } template<class T> auto operator<<(ostream &o, T x) -> decltype(x.end(), o) { o << '{'; int i = 0; for(auto e : x) o << (", ")+2*!i++ << e; return o << '}'; } #ifdef DEBUG #define debug(x...) cerr << "[" #x "]: ", [](auto... $) {((cerr << $ << "; "), ...); }(x), cerr << '\n' #else #define debug(...) {} #endif int main() { cin.tie(0)->sync_with_stdio(0); int t; cin >> t; while(t --> 0) { int n; cin >> n; string from, to; cin >> from >> to; vector<vector<int>> graph(n); REP(edge, n - 1) { int v, u; cin >> v >> u; --v, --u; graph[v].emplace_back(u); graph[u].emplace_back(v); } debug(graph); auto get_ans = [&] { bool from_has_0 = *min_element(from.begin(), from.end()) == '0'; bool from_has_1 = *max_element(from.begin(), from.end()) == '1'; bool to_has_0 = *min_element(to.begin(), to.end()) == '0'; bool to_has_1 = *max_element(to.begin(), to.end()) == '1'; debug(from_has_0, from_has_1, to_has_0, to_has_1); if(to_has_0 and to_has_1 and (not from_has_0 or not from_has_1)) return false; if(from_has_0 and from_has_1 and (not to_has_0 or not to_has_1)) return true; if(not to_has_0 and not from_has_0) return true; if(not to_has_1 and not from_has_1) return true; if(not from_has_1 and to_has_1) return false; if(not from_has_0 and to_has_0) return false; assert(to_has_0 and to_has_1 and from_has_0 and from_has_1); bool has_splitpoint_vertex = false; REP(v, n) { int cnt0 = 0, cnt1 = 0; for(int u : graph[v]) ++(to[u] == '1' ? cnt1 : cnt0); if(cnt0 > 0 and cnt1 > 0 and cnt0 + cnt1 >= 3) has_splitpoint_vertex = true; } if(has_splitpoint_vertex) return true; bool has_deg_geq3 = false; REP(v, n) if(ssize(graph[v]) >= 3) has_deg_geq3 = true; if(has_deg_geq3) { bool is_bipartite = true; REP(v, n) for(int u : graph[v]) if(to[v] == to[u]) is_bipartite = false; if(from != to and is_bipartite) return false; else return true; } else { int first = -1; REP(v, n) if(ssize(graph[v]) == 1) first = v; assert(first != -1); vector<bool> vis(n); vector<int> order = {first}; while(ssize(order) != n) { int v = order.back(); vis[v] = true; for(int u : graph[v]) if(not vis[u]) order.emplace_back(u); } debug(order); int cnt_from_0_to_1 = 0, cnt_from_1_to_0 = 0; int cnt_to_0_to_1 = 0, cnt_to_1_to_0 = 0; REP(i, n - 1) { int v = order[i]; int u = order[i + 1]; debug(v, u); cnt_from_0_to_1 += bool(from[v] == '0' and from[u] == '1'); cnt_from_1_to_0 += bool(from[v] == '1' and from[u] == '0'); cnt_to_0_to_1 += bool(to[v] == '0' and to[u] == '1'); cnt_to_1_to_0 += bool(to[v] == '1' and to[u] == '0'); } debug(cnt_from_0_to_1, cnt_from_1_to_0, cnt_to_0_to_1, cnt_to_1_to_0); if(cnt_to_1_to_0 > cnt_from_1_to_0 or cnt_to_0_to_1 > cnt_from_0_to_1 or (cnt_to_1_to_0 == cnt_from_1_to_0 and cnt_to_0_to_1 == cnt_from_0_to_1 and from[order[0]] != to[order[0]])) return false; else return true; } }; cout << (get_ans() ? "TAK" : "NIE") << '\n'; } } |