#include <bits/stdc++.h>
using namespace std;
struct FAU {
vector <int> p;
FAU(int n): p(n, -1) {}
int find(int x) {
return p[x] == -1 ? x : p[x] = find(p[x]);
}
void join(int x, int y) {
x = find(x); y = find(y);
if (x != y) {
p[x] = y;
}
}
};
bool solve(int n, int k, vector <vector<int>> &g, vector <int> &col) {
vector <vector<int>> colToNodes(k);
for (int i = 0; i < n; i++) {
colToNodes[col[i]].push_back(i);
}
FAU fau(n), fauGray(n);
for (int v = 0; v < n; v++) for (int u : g[v]) if (col[v] == col[u]) {
fau.join(u, v);
}
vector <set<pair<int,int>>> grayCompRootToAdj(n);
queue <int> colsToRemove;
vector <int> numComps(k, 0);
for (int c = 0; c < k; c++) if (colToNodes[c].empty()) {
colsToRemove.push(c);
}
for (int v = 0; v < n; v++) if (fau.p[v] == -1) {
numComps[col[v]]++;
}
for (int c = 0; c < k; c++) if (numComps[c] == 1) {
colsToRemove.push(c);
}
auto updateGrayCompAdj = [&](int p, int u) {
if (col[u] == -1) {
return ;
}
auto it = grayCompRootToAdj[p].lower_bound({col[u], -1});
if (it == grayCompRootToAdj[p].end() || it->first != col[u]) {
grayCompRootToAdj[p].insert({col[u], u});
} else {
int pu = fau.find(u), pv = fau.find(it->second);
if (pu != pv) {
fau.join(pu, pv);
numComps[col[u]]--;
if (numComps[col[u]] == 1) {
colsToRemove.push(col[u]);
}
}
}
};
int numRemoved = 0;
while (!colsToRemove.empty()) {
int c = colsToRemove.front();
colsToRemove.pop();
numRemoved++;
for (int v : colToNodes[c]) {
col[v] = -1;
for (int u : g[v]) {
int pv = fauGray.find(v);
if (col[u] == -1) {
int pu = fauGray.find(u);
if (pv != pu) {
if (grayCompRootToAdj[pv].size() > grayCompRootToAdj[pu].size()) {
swap(pu, pv);
}
fauGray.p[pv] = pu;
for (auto &e : grayCompRootToAdj[pv]) {
updateGrayCompAdj(pu, e.second);
}
grayCompRootToAdj[pv] = set <pair<int,int>> ();
}
} else {
updateGrayCompAdj(pv, u);
}
}
}
}
return numRemoved == k;
}
int main() {
ios_base::sync_with_stdio(false);
int t;
cin >> t;
while (t--) {
int n, m, k;
cin >> n >> m >> k;
vector <int> col(n);
for (int &c : col) {
cin >> c; c--;
}
vector <vector<int>> g(n);
while (m--) {
int u, v;
cin >> u >> v; u--; v--;
g[u].push_back(v);
g[v].push_back(u);
}
cout << (solve(n, k, g, col) ? "TAK\n" : "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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | #include <bits/stdc++.h> using namespace std; struct FAU { vector <int> p; FAU(int n): p(n, -1) {} int find(int x) { return p[x] == -1 ? x : p[x] = find(p[x]); } void join(int x, int y) { x = find(x); y = find(y); if (x != y) { p[x] = y; } } }; bool solve(int n, int k, vector <vector<int>> &g, vector <int> &col) { vector <vector<int>> colToNodes(k); for (int i = 0; i < n; i++) { colToNodes[col[i]].push_back(i); } FAU fau(n), fauGray(n); for (int v = 0; v < n; v++) for (int u : g[v]) if (col[v] == col[u]) { fau.join(u, v); } vector <set<pair<int,int>>> grayCompRootToAdj(n); queue <int> colsToRemove; vector <int> numComps(k, 0); for (int c = 0; c < k; c++) if (colToNodes[c].empty()) { colsToRemove.push(c); } for (int v = 0; v < n; v++) if (fau.p[v] == -1) { numComps[col[v]]++; } for (int c = 0; c < k; c++) if (numComps[c] == 1) { colsToRemove.push(c); } auto updateGrayCompAdj = [&](int p, int u) { if (col[u] == -1) { return ; } auto it = grayCompRootToAdj[p].lower_bound({col[u], -1}); if (it == grayCompRootToAdj[p].end() || it->first != col[u]) { grayCompRootToAdj[p].insert({col[u], u}); } else { int pu = fau.find(u), pv = fau.find(it->second); if (pu != pv) { fau.join(pu, pv); numComps[col[u]]--; if (numComps[col[u]] == 1) { colsToRemove.push(col[u]); } } } }; int numRemoved = 0; while (!colsToRemove.empty()) { int c = colsToRemove.front(); colsToRemove.pop(); numRemoved++; for (int v : colToNodes[c]) { col[v] = -1; for (int u : g[v]) { int pv = fauGray.find(v); if (col[u] == -1) { int pu = fauGray.find(u); if (pv != pu) { if (grayCompRootToAdj[pv].size() > grayCompRootToAdj[pu].size()) { swap(pu, pv); } fauGray.p[pv] = pu; for (auto &e : grayCompRootToAdj[pv]) { updateGrayCompAdj(pu, e.second); } grayCompRootToAdj[pv] = set <pair<int,int>> (); } } else { updateGrayCompAdj(pv, u); } } } } return numRemoved == k; } int main() { ios_base::sync_with_stdio(false); int t; cin >> t; while (t--) { int n, m, k; cin >> n >> m >> k; vector <int> col(n); for (int &c : col) { cin >> c; c--; } vector <vector<int>> g(n); while (m--) { int u, v; cin >> u >> v; u--; v--; g[u].push_back(v); g[v].push_back(u); } cout << (solve(n, k, g, col) ? "TAK\n" : "NIE\n"); } return 0; } |
English