先用字典并查集合并所有相等约束,再检查每条不等约束的两端是否落在同一集合。
OJ: luogu
题目 ID: P1955
难度:普及+/提高
标签:并查集离散化python
日期: 2026-07-16 17:48
题意
判断若干形如
思路
相等关系具有传递性,先把所有相等约束放进并查集。随后逐条检查不等约束:若两端已经属于同一集合,就产生矛盾。
变量编号可达 dict 以原编号为键,相当于把离散化和并查集存储合在一起。
Python 知识
- 字典推导式从约束中收集实际出现的变量,参见
/home/rainboy/mycode/hugo-blog/content/program_language/python/dict_usage.md。 all(...)会在第一个矛盾处短路,不会继续做无用检查。dict.fromkeys(parent, 1)为所有根初始化集合大小。
代码
python
import sys
data = iter(map(int, sys.stdin.buffer.read().split()))
answers = []
for _ in range(next(data)):
constraints = [(next(data), next(data), next(data)) for _ in range(next(data))]
parent = {x: x for constraint in constraints for x in constraint[:2]}
size = dict.fromkeys(parent, 1)
def find(x):
while parent[x] != x:
parent[x] = parent[parent[x]]
x = parent[x]
return x
def union(x, y):
x, y = find(x), find(y)
if x == y:
return
if size[x] < size[y]:
x, y = y, x
parent[y] = x
size[x] += size[y]
for x, y, equal in constraints:
if equal:
union(x, y)
answers.append("YES" if all(
equal or find(x) != find(y) for x, y, equal in constraints
) else "NO")
print("\n".join(answers))复杂度
设约束数为
总结
先处理“必须相等”,再验证“必须不等”,即可把约束满足转成并查集判冲突。