#include using namespace std; //此题,数据范围太大,必须离散化处理(这是策略二,还需要一种简单版本的离散化) //关注一下数据范围,是有10的9次方那么大,如果开一个10的9次方大的fa数组的话,空间肯定超限,超限就凉凉 int t;//表示需要判定的问题个数 int n;//表示该问题中需要被满足的约束条件个数 int x; //第一个数 int y; //第二个数 int e; //是否相等,1相等,0不相等 const int N = 1000010; int fa[N]; //要深入理解这个递归并压缩的过程 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; } //先记录,再离散化 struct Node { int x, y, e; } a[N]; //先处理相等,再处理不相等的,这个排序器是用来决定相等优先的 bool cmp(const Node &a, const Node &b) { return a.e > b.e; } int main() { cin >> t; while (t--) { cin >> n; //初始化 memset(a, 0, sizeof a); memset(fa, 0, sizeof fa); //录入+离散化 vector alls; // 存储所有待离散化的值 for (int i = 1; i <= n; i++) { cin >> a[i].x >> a[i].y >> a[i].e; alls.push_back(a[i].x), alls.push_back(a[i].y); } // 将所有值排序 sort(alls.begin(), alls.end()); // 去掉重复元素 alls.erase(unique(alls.begin(), alls.end()), alls.end()); // 二分求出x对应的离散化的值 for (int i = 1; i <= n; i++) { a[i].x = lower_bound(alls.begin(), alls.end(), a[i].x) - alls.begin(); a[i].y = lower_bound(alls.begin(), alls.end(), a[i].y) - alls.begin(); } //排序,先处理相等的,再处理不相等的.这样才能保证亲戚都认领完了,再找出矛盾。 sort(a + 1, a + 1 + n, cmp); //初始化并查集 for (int i = 1; i <= alls.size(); 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; }