#include "bits/stdc++.h"
using namespace std;
using ll = long long;
void solve() {
int n, m, k;
cin >> n >> m >> k;
vector <int> a(n + 1), cnt(k + 1, 0);
for (int i = 1; i <= n; i++) {
cin >> a[i];
cnt[a[i]]++;
}
vector <int> parent, ile;
parent.resize(n + 1);
ile.resize(n + 1);
for (int i = 1; i <= n; i++) {
parent[i] = i;
ile[i] = 1;
}
auto Find = [&](this auto Find, int n) -> int {
if (parent[n] == n) return n;
return parent[n] = Find(parent[n]);
};
vector <map <int, int>> edges(n + 1);
vector <vector <int>> groups(k + 1);
vector <bool> vis(n + 1, false);
queue <int> q;
auto Union = [&](this auto Union, int x, int y) -> bool {
x = Find(x);
y = Find(y);
if (x == y) return false;
if (ile[x] < ile[y]) swap(x, y);
ile[x] += ile[y];
parent[y] = x;
if (edges[x].size() < edges[y].size()) swap(edges[x], edges[y]);
for (auto [color, v] : edges[y]) {
if (edges[x].contains(color)) {
if (Union(edges[x][color], v)) {
if (--cnt[color] == 1) {
for (auto e : groups[color]) {
q.push(e);
vis[e] = true;
}
}
}
} else {
edges[x][color] = v;
}
}
return true;
};
vector <vector <int>> g(n + 1);
for (int i = 0; i < m; i++) {
int x, y;
cin >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
if (a[x] == a[y] && Union(x, y)) cnt[a[x]]--;;
}
vector <vector <int>> G(n + 1);
vector <bool> tmp_used(n + 1, false);
for (int i = 1; i <= n; i++) {
int x = Find(i);
if (!tmp_used[x]) {
tmp_used[x] = true;
groups[a[x]].push_back(x);
}
}
for (int i = 1; i <= n; i++) {
for (auto e : g[i]) {
int x = Find(i);
int y = Find(e);
if (x != y) {
G[x].push_back(y);
G[y].push_back(x);
}
}
}
for (int i = 1; i <= k; i++) {
if (cnt[i] == 1) {
for (auto x : groups[i]) {
q.push(x);
vis[x] = true;
}
}
}
while (!q.empty()) {
auto v = q.front();
q.pop();
for (auto e : G[v]) {
if (vis[e]) Union(v, e);
}
int x = Find(v);
for (auto e : G[v]) if (!vis[e]) {
if (edges[x].contains(a[e])) {
if (Union(edges[x][a[e]], e)) {
if (--cnt[a[e]] == 1) {
for (auto y : groups[a[e]]) {
vis[y] = true;
q.push(y);
}
}
}
} else {
edges[x][a[e]] = e;
}
}
}
cout << (*max_element(cnt.begin(), cnt.end()) <= 1 ? "TAK\n" : "NIE\n");
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int t;
cin >> t;
while (t--) solve();
}
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 | #include "bits/stdc++.h" using namespace std; using ll = long long; void solve() { int n, m, k; cin >> n >> m >> k; vector <int> a(n + 1), cnt(k + 1, 0); for (int i = 1; i <= n; i++) { cin >> a[i]; cnt[a[i]]++; } vector <int> parent, ile; parent.resize(n + 1); ile.resize(n + 1); for (int i = 1; i <= n; i++) { parent[i] = i; ile[i] = 1; } auto Find = [&](this auto Find, int n) -> int { if (parent[n] == n) return n; return parent[n] = Find(parent[n]); }; vector <map <int, int>> edges(n + 1); vector <vector <int>> groups(k + 1); vector <bool> vis(n + 1, false); queue <int> q; auto Union = [&](this auto Union, int x, int y) -> bool { x = Find(x); y = Find(y); if (x == y) return false; if (ile[x] < ile[y]) swap(x, y); ile[x] += ile[y]; parent[y] = x; if (edges[x].size() < edges[y].size()) swap(edges[x], edges[y]); for (auto [color, v] : edges[y]) { if (edges[x].contains(color)) { if (Union(edges[x][color], v)) { if (--cnt[color] == 1) { for (auto e : groups[color]) { q.push(e); vis[e] = true; } } } } else { edges[x][color] = v; } } return true; }; vector <vector <int>> g(n + 1); for (int i = 0; i < m; i++) { int x, y; cin >> x >> y; g[x].push_back(y); g[y].push_back(x); if (a[x] == a[y] && Union(x, y)) cnt[a[x]]--;; } vector <vector <int>> G(n + 1); vector <bool> tmp_used(n + 1, false); for (int i = 1; i <= n; i++) { int x = Find(i); if (!tmp_used[x]) { tmp_used[x] = true; groups[a[x]].push_back(x); } } for (int i = 1; i <= n; i++) { for (auto e : g[i]) { int x = Find(i); int y = Find(e); if (x != y) { G[x].push_back(y); G[y].push_back(x); } } } for (int i = 1; i <= k; i++) { if (cnt[i] == 1) { for (auto x : groups[i]) { q.push(x); vis[x] = true; } } } while (!q.empty()) { auto v = q.front(); q.pop(); for (auto e : G[v]) { if (vis[e]) Union(v, e); } int x = Find(v); for (auto e : G[v]) if (!vis[e]) { if (edges[x].contains(a[e])) { if (Union(edges[x][a[e]], e)) { if (--cnt[a[e]] == 1) { for (auto y : groups[a[e]]) { vis[y] = true; q.push(y); } } } } else { edges[x][a[e]] = e; } } } cout << (*max_element(cnt.begin(), cnt.end()) <= 1 ? "TAK\n" : "NIE\n"); } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int t; cin >> t; while (t--) solve(); } |
English