1
+ class DSU :
2
+ def __init__ (self , n ):
3
+ self .parent = list (range (n ))
4
+ self .size = [1 ] * n
5
+
6
+ def find (self , a ):
7
+ if a == self .parent [a ]:
8
+ return a
9
+ self .parent [a ] = self .find (self .parent [a ])
10
+ return self .parent [a ]
11
+
12
+ def union (self , a , b ):
13
+ parent_a = self .find (a )
14
+ parent_b = self .find (b )
15
+ if parent_a != parent_b :
16
+ if self .size [parent_a ] < self .size [parent_b ]:
17
+ parent_a , parent_b = parent_b , parent_a
18
+ self .parent [parent_b ] = parent_a
19
+ self .size [parent_a ] += self .size [parent_b ]
20
+
21
+ class DistanceLimitedPathsExist :
22
+ def __init__ (self , n : int , edgeList : List [List [int ]]):
23
+ graph = [[] for _ in range (n )]
24
+ edgeList .sort (key = lambda p : p [2 ])
25
+ dsu = DSU (n )
26
+ for u , v , w in edgeList :
27
+ if dsu .find (u ) != dsu .find (v ):
28
+ graph [u ].append ((v , w ))
29
+ graph [v ].append ((u , w ))
30
+ dsu .union (u , v )
31
+ LOG = 2
32
+ p = 1
33
+ while p <= n :
34
+ LOG += 1
35
+ p *= 2
36
+ depth = [0 ] * n
37
+ parent = [[i ] * LOG for i in range (n )]
38
+ mxedge = [[float ('-inf' )] * LOG for i in range (n )]
39
+ v = [False ] * n
40
+ for src in range (n ):
41
+ if v [src ]:
42
+ continue
43
+ stack = [(src , 0 , - 1 )]
44
+ while stack :
45
+ i , d , p = stack .pop ()
46
+ depth [i ] = d
47
+ v [i ] = True
48
+ for j , w in graph [i ]:
49
+ if j != p :
50
+ parent [j ][0 ] = i
51
+ mxedge [j ][0 ] = w
52
+ stack .append ((j , d + 1 , i ))
53
+ for jump in range (1 , LOG ):
54
+ for i in range (n ):
55
+ mxedge [i ][jump ] = max (mxedge [i ][jump - 1 ], mxedge [parent [i ][jump - 1 ]][jump - 1 ])
56
+ parent [i ][jump ] = parent [parent [i ][jump - 1 ]][jump - 1 ]
57
+ self .dsu = dsu
58
+ self .parent = parent
59
+ self .mxedge = mxedge
60
+ self .depth = depth
61
+ self .LOG = LOG
62
+
63
+ def query (self , p : int , q : int , limit : int ) -> bool :
64
+ if self .dsu .find (p ) != self .dsu .find (q ):
65
+ return False
66
+ bigedge = float ('-inf' )
67
+ if self .depth [p ] > self .depth [q ]:
68
+ p , q = q , p
69
+ diff = self .depth [q ] - self .depth [p ]
70
+ jump = 0
71
+ while diff :
72
+ if diff & 1 :
73
+ bigedge = max (bigedge , self .mxedge [q ][jump ])
74
+ q = self .parent [q ][jump ]
75
+ diff //= 2
76
+ jump += 1
77
+ for jump in range (self .LOG - 1 , - 1 , - 1 ):
78
+ if self .parent [p ][jump ] != self .parent [q ][jump ]:
79
+ bigedge = max (bigedge , self .mxedge [p ][jump ], self .mxedge [q ][jump ])
80
+ p = self .parent [p ][jump ]
81
+ q = self .parent [q ][jump ]
82
+ if p != q :
83
+ bigedge = max (bigedge , self .mxedge [p ][0 ], self .mxedge [q ][0 ])
84
+ return bigedge < limit
0 commit comments