#2错了,不懂为什么。
#define _CRT_SECURE_NO_WARNINGS
#define Max 100005
#define Mod 99991
#include <stdio.h>
//并查集
//2.0哈希表+离散化+并查集
//error
struct node
{
long long int x;//真实值
long long int y;
int e;
};
struct board
{
long long int map;
int rel;
};
struct node sign[Max] = { 0 };
struct board Hash[2 * Max] = { 0 };//Hash、祖先
long long int read()
{
long long int num = 0;
char ch = getchar();
while (ch < '0' || '9' < ch)//找首位
{
ch = getchar();
}
while ('0' <= ch && ch <= '9')//数值
{
num = num * 10 + ch - '0';
ch = getchar();
}
return num;
}
void first()
{
if (Hash[0].rel)//特例
{
Hash[0].rel = 0;
}
for (int i = 1; i < 2 * Max; i++)
{
if (Hash[i].map)
{
Hash[i].map = 0;
if (Hash[i].rel)
{
Hash[i].rel = 0;
}
}
}
}
void exchange(int l, int r)
{
sign[l].x ^= sign[r].x;//换x真实值
sign[r].x ^= sign[l].x;
sign[l].x ^= sign[r].x;
sign[l].y ^= sign[r].y;//换y真实值
sign[r].y ^= sign[l].y;
sign[l].y ^= sign[r].y;
//换e
sign[l].e = 1;
sign[r].e = 0;
}
int sort(int l, int r)
{
while (l < r)
{
while (r > l)//r找true
{
if (sign[r].e)
{
break;
}
r--;
}
while (l < r)//l找false
{
if (!sign[l].e)
{
break;
}
l++;
}
if (l < r)//交换
{
exchange(l, r);
}
}
return (sign[l].e ? l : l - 1);//返回最后的true的下标
}
int set(int sit)
{
int i = 0;
for (; sit + i < 2 * Max; i++)
{
if (Hash[sit + i].map == sit)//是否有了
{
break;
}
if (Hash[sit + i].map == 0)//找空位
{
Hash[sit + i].map = sit;
break;
}
}
return sit + i;
}
int find(int x)//压缩路径
{
if (Hash[x].rel == 0)
{
return x;
}
return Hash[x].rel = find(Hash[x].rel);
}
void join(int s_x, int s_y)
{
//找映射值的祖先
int fx = find(s_x), fy = find(s_y);
if (fx != fy)//是否合并
{
Hash[fx].rel = fy;
}
}
int main()
{
int t = (int)read();
while (t--)
{
int n = (int)read();//条件数
int flag = 1;
first();//初始化
for (int i = 1; i <= n; i++)//条件
{
sign[i].x = read(), sign[i].y = read();
sign[i].e = (int)read();
}
int end = sort(1, n);//条件排序-简化快排、1前、返回1的个数
for (int i = 1; i <= end; i++)//true
{
//sign[i].x1 = sign[i].x % Mod;//计算映射值
//sign[i].y1 = sign[i].y % Mod;
//set(&sign[i].x1);//放入Hash表中
//set(&sign[i].y1);//开放地址法、返回下标
join(set(sign[i].x % Mod), set(sign[i].y % Mod));//并集合
}
for (int i = end + 1; i <= n; i++)//false
{
//sign[i].x1 = sign[i].x % Mod;//计算映射值
//sign[i].y1 = sign[i].y % Mod;
//find(set(&sign[i].x1));//找祖先
//find(set(&sign[i].y1));
//是否满足
if (find(set(sign[i].x % Mod)) == find(set(sign[i].y % Mod)))
{
flag = 0;
break;
}
}
if (flag)//输出
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}