#include using namespace std; int t;//表示需要判定的问题个数 int n;//表示该问题中需要被满足的约束条件个数 int x; //第一个数 int y; //第二个数 int e; //是否相等,1相等,0不相等 const int N = 1e6 + 10; int fa[N]; //先记录,再离散化 struct Node { int x, y, e; } a[N]; //先处理相等,再处理不相等的,这个排序器是用来决定相等优先的 bool cmp(const Node &a, const Node &b) { return a.e > b.e; } //要深入理解这个递归并压缩的过程 int find(int x) { if (fa[x] != x) fa[x] = find(fa[x]); return fa[x]; } //加入家族集合中 void join(int c1, int c2) { int f1 = find(c1), f2 = find(c2); if (f1 != f2)fa[f1] = f2; } int main() { cin >> t; while (t--) { cin >> n; //初始化,因为有多个问题,每个问题问之前,都需要清理下场地 memset(a, 0, sizeof a); memset(fa, 0, sizeof fa); //录入 for (int i = 1; i <= n; i++) cin >> a[i].x >> a[i].y >> a[i].e; //排序,先处理相等的,再处理不相等的.这样才能保证亲戚都认领完了,再找出矛盾。 sort(a + 1, a + 1 + n, cmp); //初始化并查集 for (int i = 1; i < N; i++) fa[i] = i; bool success = true; for (int i = 1; i <= n; i++) { if (a[i].e == 1) join(a[i].x, a[i].y); else { int f1 = find(a[i].x), f2 = find(a[i].y); if (f1 == f2) { success = false; break; } } } if (success) cout << "YES" << endl; else cout << "NO" << endl; } return 0; }