#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
vector<int> parent, sizes;
int n, setCount;
UnionFind(int _n) : n(_n), setCount(_n), parent(_n), sizes(_n, 1) {
iota(parent.begin(), parent.end(), 0);
}
int Find(int a) {
if (parent[a] != a) parent[a] = Find(parent[a]);
return parent[a];
}
bool Union(int x, int y) {
int rx = Find(x), ry = Find(y);
if (rx == ry) return false;
if (sizes[rx] > sizes[ry]) swap(rx, ry);
parent[rx] = ry;
sizes[ry] += sizes[rx];
setCount--;
return true;
}
};
void solve(int testcase) {
int n;
cin >> n;
vector<tuple<int, int, int>> edges;
unordered_set<int> S;
for (int i = 0; i < n; i++) {
int u, v, w;
cin >> u >> v >> w;
u--;
v--;
S.insert(u);
S.insert(v);
edges.emplace_back(u, v, w);
}
vector<int> nodes(S.begin(), S.end());
unordered_map<int, int> d;
for (int i = 0; i < nodes.size(); i++) {
d[nodes[i]] = i;
}
UnionFind uf(nodes.size());
vector<pair<int, int>> uneq;
for (auto& [u, v, e] : edges) {
if (e == 1) {
uf.Union(d[u], d[v]);
} else {
uneq.emplace_back(d[u], d[v]);
}
}
for (auto& [u, v] : uneq) {
if (uf.Find(u) == uf.Find(v)) {
cout << "NO" << "\n";
return;
}
}
cout << "YES" << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(nullptr);
int T;
cin >> T;
for (int t = 0; t < T; t++) {
solve(t);
}
return 0;
}
离散化+并查集

京公网安备 11010502036488号