def__init__(self, n: int): self.n = n self.pa = list(range(n)) # 父節點 self.sz = [1] * n # 連通分量大小 self.cnt = n # 連通分量數量
deffind(self, x: int) -> int: """Iterative version, path halving""" while self.pa[x] != x: self.pa[x] = self.pa[self.pa[x]] x = self.pa[x] return x
defunion(self, x: int, y: int) -> bool: fx, fy = self.find(x), self.find(y) if fx == fy: returnFalse if self.sz[fx] < self.sz[fy]: fx, fy = fy, fx self.pa[fy] = fx self.sz[fx] += self.sz[fy] self.cnt -= 1 returnTrue
defsolve(): n = int(input()) Xs = set() constraints = [[] for _ inrange(2)] for _ inrange(n): a, b, e = map(int, input().split()) constraints[e].append((a, b)) Xs.add(a) Xs.add(b)
Xs = sorted(Xs) mp = {x: i for i, x inenumerate(Xs)} m = len(Xs)
uf = UnionFind(m) for a, b in constraints[1]: uf.union(mp[a], mp[b]) for a, b in constraints[0]: if uf.find(mp[a]) == uf.find(mp[b]): print("NO") break else: print("YES")
if __name__ == "__main__": t = int(input()) for _ inrange(t): solve()
defsolve(): n = int(input()) Xs = set() constraints = [] for _ inrange(n): a, b, e = map(int, input().split()) constraints.append((a, b, e)) Xs.add(a) Xs.add(b)
Xs = sorted(Xs) mp = {x: i for i, x inenumerate(Xs)} m = len(Xs)
fa = list(range(m)) # 父節點 diffs = [set() for _ inrange(m)] # diffs[u] 表示與需與 u 不同的節點集合
deffind(x): while fa[x] != x: fa[x] = fa[fa[x]] x = fa[x] return x
for a, b, e in constraints: x, y = mp[a], mp[b] fx, fy = find(x), find(y) if e == 1: # 相等關係 if fx == fy: continue # 啟發式合併,讓 fy 是較小的集合 iflen(diffs[fx]) < len(diffs[fy]): fx, fy = fy, fx ifany(find(u) == fx for u in diffs[fy]): print("NO") break fa[fy] = fx diffs[fx].update(diffs[fy]) diffs[fy].clear() else: # 相異關係 if fx == fy: print("NO") break diffs[fx].add(y) diffs[fy].add(x) else: print("YES")