Giả sử chúng ta có một đồ thị có trọng số vô hướng với n nút sử dụng một edgeList, trong đó edgeList [i] có ba tham số (u, v, w) biểu thị có một đường đi từ u đến v có khoảng cách là w. Chúng ta cũng có một mảng truy vấn khác trong đó truy vấn [i] có (p, q, lim). Truy vấn này đang cố gắng hỏi liệu có một đường dẫn (trực tiếp hoặc qua một số nút khác) từ p đến q có khoảng cách nhỏ hơn lim hay không. Chúng ta phải trả về một mảng chứa các kết quả Đúng / Sai cho mỗi truy vấn.
Vì vậy, nếu đầu vào giống như
thì đầu ra sẽ là [True, False, True]. Bởi vì để đi từ 1 đến 4, chúng ta có thể đi theo con đường 1 -> 3 -> 4 với chi phí 11, con đường thứ hai là sai vì chúng ta không thể đi từ 2 đến 3 bằng cách sử dụng ít hơn 3, và con đường cuối cùng đúng vì chúng ta có thể đi từ 1 đến 2 bằng cách sử dụng đường dẫn 1 -> 3 -> 2 với chi phí 14 là nhỏ hơn 15.
Để giải quyết vấn đề này, chúng tôi sẽ làm theo các bước sau -
-
cha mẹ:=một danh sách từ 0 đến n
-
rank:=danh sách có kích thước n + 1 và điền bằng 0
-
Định nghĩa một hàm find (). Điều này sẽ đưa cha mẹ, x
-
nếu cha [x] giống với x thì
-
trả lại x
-
-
cha [x]:=find (cha, cha [x])
-
trả về cha mẹ [x]
-
Định nghĩa một hàm union (). Điều này sẽ lấy cha mẹ, a, b
-
a:=find (cha, a)
-
b:=find (cha, b)
-
nếu a giống với b thì
-
trở lại
-
-
nếu xếp hạng [a]
-
cha [a]:=b
-
-
ngược lại khi xếp hạng [a]> xếp hạng [b] thì
-
cha [b]:=a
-
-
nếu không,
-
cha [b]:=a
-
rank [a]:=rank [a] + 1
-
-
Từ phương thức chính, hãy làm như sau -
-
sắp xếp edgeList dựa trên thông số trọng lượng
-
res:=một mảng có số lượng truy vấn và điền bằng 0
-
truy vấn:=danh sách các cặp (i, ch) cho mỗi chỉ mục i và giá trị ch từ các truy vấn
-
sắp xếp các truy vấn dựa trên các tham số giới hạn
-
ind:=0
-
đối với mỗi chỉ mục tôi ba lần (a, b, w) trong các truy vấn, thực hiện
-
while ind
-
union (cha, edgeList [ind, 0])
-
ind:=ind + 1
-
-
res [i]:=find (cha, a) giống như find (cha, b)
-
-
trả lại res
Ví dụ
Hãy cùng chúng tôi xem cách triển khai sau để hiểu rõ hơn
def solve(n, edgeList, queries): parent = [i for i in range(n+1)] rank = [0 for i in range(n+1)] def find(parent, x): if parent[x] == x: return x parent[x] = find(parent, parent[x]) return parent[x] def union(parent, a, b): a = find(parent, a) b = find(parent, b) if a == b: return if rank[a] < rank[b]: parent[a] = b elif rank[a] > rank[b]: parent[b] = a else: parent[b] = a rank[a] += 1 edgeList.sort(key = lambda x: x[2]) res = [0] * len(queries) queries = [[i, ch] for i, ch in enumerate(queries)] queries.sort(key = lambda x: x[1][2]) ind = 0 for i, (a, b, w) in queries: while ind < len(edgeList) and edgeList[ind][2] < w: union(parent, edgeList[ind][0], edgeList[ind][1]) ind += 1 res[i] = find(parent, a) == find(parent, b) return res n = 4 edgeList = [(1,2,16),(1,3,8),(2,4,3),(2,3,6),(4,3,3),] queries = [(1,4,12),(2,3,3),(1,2,15)] print(solve(n, edgeList, queries))
Đầu vào
4, [(1,2,16),(1,3,8),(2,4,3),(2,3,6),(4,3,3)],[(1,4,12),(2,3,3),(1,2,15)]
Đầu ra
[True, False, True]