M27306: 植物观察
disjoint set, bfs, http://cs101.openjudge.cn/practice/27306/
周末,小明和他的朋友们去野外观察植物,并拍了 n 张植物的照片回来。社团的前辈告诉他们,照片上所有这些植物都属于两个不同种类 A、B 中的某一种。由于是新手,小明很难直接判断每张照片上的植物属于哪个种类。但是,如果把植物的照片两两组合对比来看,小明能够判断其中一些组合的两个植物是属于相同还是不同的种类。经过一番研究,小明最终得出了 m 组这样的结论。他希望知道,这 m 组结论是否可能同时成立。具体来说,是否存在一种给每个植物分类为 A 或 B 的方法,使得小明的每组结论对于两个植物种类相同或不同的判断均正确。
输入
第一行为两个整数,分别是植物的数量 n 和结论的个数 m。n <= 100, m <= 10000
接下来 m 行,每行为一个结论,包括三个整数,前两个整数表示植物的编号(从 0 到 n-1),第三个整数表示小明的判断,0 代表相同,1 代表不同。
输出
如果所有结论可能同时成立,输出 “YES”,否则输出 “NO”。
样例输入
Sample1 Input:
3 3
0 1 0
1 2 1
0 2 1
Sample1 Output:
YES
解释:分类方案:植物0:A,植物1:A,植物2:B,能够使所有结论同时成立。样例输出
Sample2 Input:
3 3
0 1 0
1 2 1
0 2 0
Sample2 Output:
NO
解释:所有结论不可能同时成立。提示
tag: disjoint set, bfs
来源
2023fall zyn
【林茂融 2025fall-cs201 城市与环境学院】思路:这道题是很典型的并查集,课上也提到过。实际上,标记为0的就是边,1的只要单独记录,把边union以后检查标记为1的元素是否连通就行了。考试的时候快速AC了。
python
n, m = map(int, input().split())
parent=[i for i in range(n)]
edges=[]
diff=[]
for _ in range(m):
a, b, c = map(int, input().split())
if c!=1:
edges.append((a, b))
else:
diff.append((a, b))
def find(x):
if parent[x] != x:
parent[x] = find(parent[x])
return parent[x]
def union(x, y):
nx, ny = find(x), find(y)
if nx != ny:
parent[ny] = nx
#return True
#return False
for a, b in edges:
union(a, b)
for a, b in diff:
if find(a) == find(b):
print('NO')
exit()
print('YES')python
class UnionFind:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n
def find(self, x):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x])
return self.parent[x]
def union(self, x, y):
root_x = self.find(x)
root_y = self.find(y)
if root_x != root_y:
if self.rank[root_x] > self.rank[root_y]:
self.parent[root_y] = root_x
elif self.rank[root_x] < self.rank[root_y]:
self.parent[root_x] = root_y
else:
self.parent[root_y] = root_x
self.rank[root_x] += 1
def can_classify_plants(n, relations):
uf = UnionFind(n * 2)
for x, y, relation in relations:
if relation == 0: # Same group
if uf.find(x) == uf.find(y + n) or uf.find(y) == uf.find(x + n):
return "NO"
uf.union(x, y)
uf.union(x + n, y + n)
else: # Different groups
if uf.find(x) == uf.find(y):
return "NO"
uf.union(x, y + n)
uf.union(y, x + n)
return "YES"
# Input
n, m = map(int, input().split())
relations = [tuple(map(int, input().split())) for _ in range(m)]
# Output
print(can_classify_plants(n, relations))