题目
小美认为,在人际交往中,但是随着时间的流逝,朋友的关系也是会慢慢变淡的,最终朋友关系就淡忘了。
现在初始有一些朋友关系,存在一些事件会导致两个人淡忘了他们的朋友关系。小美想知道某一时刻中,某两人是否可以通过朋友介绍互相认识?
事件共有 2 种:
1. u v:代表编号 u 的人和编号 v 的人淡忘了他们的朋友关系。
2. u v:代表小美查询编号 u 的人和编号 v 的人是否能通过朋友介绍互相认识。
输入
第一行输入三个正整数 n, m, q,代表总人数,初始的朋友关系数量,发生的事件数量。
接下来 m 行,每行输入两个正整数 u, v,代表初始编号 u 的人和编号 v 的人是朋友关系。
接下来 q 行,每行输入三个正整数 op, u, v,含义如题目描述所述。
保证至少存在一次查询操作
示例
输入:
5 3 5 1 2 2 3 4 5 1 1 5 2 1 3 2 1 4 1 1 2 2 1 3输出:
Yes No No
代码
import sys
from collections import defaultdict
class DisjointSet:
def __init__(self) -> None:
# 因为 n 可能很大,用 list 太大了
self.p = {}
def find(self, x):
if x not in self.p:
return x
if self.p[x] != x:
self.p[x] = self.find(self.p[x])
return self.p[x]
def union(self, x, y):
px = self.find(x)
py = self.find(y)
if px != py:
self.p[py] = px
if __name__ == '__main__':
N, M, Q = map(int, sys.stdin.readline().strip().split())
relats = defaultdict(set)
for _ in range(M):
u, v = map(int, sys.stdin.readline().strip().split())
relats[u].add(v)
events = []
for _ in range(Q):
op, u, v = map(int, sys.stdin.readline().strip().split())
if op == 1:
if v in relats[u]:
relats[u].remove(v)
events.append((op, u, v))
elif u in relats[v]:
relats[v].remove(u)
events.append((op, u, v))
else:
events.append((op, u, v))
ds = DisjointSet()
# 超时的主要原因,n 太大,没必要为了空间复杂度增加时间复杂度
# for i in range(1, N+1):
# for j in range(i+1, N+1):
# if j in relats[i]:
# # ds.p[i] = i
# # ds.p[j] = i
# ds.union(i, j)
for k, v in relats.items():
for j in v:
ds.union(k, j)
print_str = ''
while(events):
op, u, v = events.pop()
if op == 1:
ds.union(u, v)
else:
if ds.find(u) == ds.find(v):
print_str = 'Yes\n' + print_str
else:
print_str = 'No\n' + print_str
sys.stdout.write(print_str)
时间复杂度:O(max(m, n) * n)
该方法中没有使用 rank 压缩路径,使用后并查集合并的时间复杂度为 ,则总时间复杂度变为