@@ -107,32 +107,306 @@ tags:
107107
108108<!-- solution:start -->
109109
110- ### 方法一
110+ ### 方法一:并查集
111+
112+ 我们可以将边按时间从小到大排序,然后从时间最大的边开始依次将边加入图中,同时使用并查集维护当前图的连通分量数量。当连通分量数量小于 $k$ 时,说明当前时间即为所求的最小时间。
113+
114+ 时间复杂度 $O(n \times \alpha(n))$,空间复杂度 $O(n)$,其中 $\alpha$ 是反阿克曼函数。
111115
112116<!-- tabs:start -->
113117
114118#### Python3
115119
116120``` python
117-
121+ class UnionFind :
122+ def __init__ (self , n ):
123+ self .p = list (range (n))
124+ self .size = [1 ] * n
125+
126+ def find (self , x ):
127+ if self .p[x] != x:
128+ self .p[x] = self .find(self .p[x])
129+ return self .p[x]
130+
131+ def union (self , a , b ):
132+ pa, pb = self .find(a), self .find(b)
133+ if pa == pb:
134+ return False
135+ if self .size[pa] > self .size[pb]:
136+ self .p[pb] = pa
137+ self .size[pa] += self .size[pb]
138+ else :
139+ self .p[pa] = pb
140+ self .size[pb] += self .size[pa]
141+ return True
142+
143+
144+ class Solution :
145+ def minTime (self , n : int , edges : List[List[int ]], k : int ) -> int :
146+ edges.sort(key = lambda x : x[2 ])
147+ uf = UnionFind(n)
148+ cnt = n
149+ for u, v, t in edges[::- 1 ]:
150+ if uf.union(u, v):
151+ cnt -= 1
152+ if cnt < k:
153+ return t
154+ return 0
118155```
119156
120157#### Java
121158
122159``` java
123-
160+ class UnionFind {
161+ private int [] p;
162+ private int [] size;
163+
164+ public UnionFind (int n ) {
165+ p = new int [n];
166+ size = new int [n];
167+ for (int i = 0 ; i < n; i++ ) {
168+ p[i] = i;
169+ size[i] = 1 ;
170+ }
171+ }
172+
173+ public int find (int x ) {
174+ if (p[x] != x) {
175+ p[x] = find(p[x]);
176+ }
177+ return p[x];
178+ }
179+
180+ public boolean union (int a , int b ) {
181+ int pa = find(a);
182+ int pb = find(b);
183+ if (pa == pb) {
184+ return false ;
185+ }
186+
187+ if (size[pa] > size[pb]) {
188+ p[pb] = pa;
189+ size[pa] += size[pb];
190+ } else {
191+ p[pa] = pb;
192+ size[pb] += size[pa];
193+ }
194+ return true ;
195+ }
196+ }
197+
198+ class Solution {
199+ public int minTime (int n , int [][] edges , int k ) {
200+ Arrays . sort(edges, (a, b) - > Integer . compare(a[2 ], b[2 ]));
201+
202+ UnionFind uf = new UnionFind (n);
203+ int cnt = n;
204+
205+ for (int i = edges. length - 1 ; i >= 0 ; i-- ) {
206+ int u = edges[i][0 ];
207+ int v = edges[i][1 ];
208+ int t = edges[i][2 ];
209+
210+ if (uf. union(u, v)) {
211+ if (-- cnt < k) {
212+ return t;
213+ }
214+ }
215+ }
216+ return 0 ;
217+ }
218+ }
124219```
125220
126221#### C++
127222
128223``` cpp
129-
224+ class UnionFind {
225+ public:
226+ vector<int > p;
227+ vector<int > size;
228+
229+ UnionFind(int n) {
230+ p.resize(n);
231+ size.resize(n, 1);
232+ for (int i = 0; i < n; i++) {
233+ p[i] = i;
234+ }
235+ }
236+
237+ int find (int x) {
238+ if (p[ x] != x) {
239+ p[ x] = find(p[ x] );
240+ }
241+ return p[ x] ;
242+ }
243+
244+ bool unite(int a, int b) {
245+ int pa = find(a);
246+ int pb = find(b);
247+ if (pa == pb) {
248+ return false;
249+ }
250+
251+ if (size[pa] > size[pb]) {
252+ p[pb] = pa;
253+ size[pa] += size[pb];
254+ } else {
255+ p[pa] = pb;
256+ size[pb] += size[pa];
257+ }
258+ return true;
259+ }
260+ };
261+
262+ class Solution {
263+ public:
264+ int minTime(int n, vector<vector<int >>& edges, int k) {
265+ sort(edges.begin(), edges.end(), [ ] (const vector<int >& a, const vector<int >& b) {
266+ return a[ 2] < b[ 2] ;
267+ });
268+
269+ UnionFind uf(n);
270+ int cnt = n;
271+
272+ for (int i = edges.size() - 1; i >= 0; i--) {
273+ int u = edges[i][0];
274+ int v = edges[i][1];
275+ int t = edges[i][2];
276+
277+ if (uf.unite(u, v)) {
278+ cnt--;
279+ if (cnt < k) {
280+ return t;
281+ }
282+ }
283+ }
284+ return 0;
285+ }
286+ };
130287```
131288
132289#### Go
133290
134291```go
292+ type UnionFind struct {
293+ p []int
294+ size []int
295+ }
296+
297+ func NewUnionFind(n int) *UnionFind {
298+ uf := &UnionFind{
299+ p: make([]int, n),
300+ size: make([]int, n),
301+ }
302+ for i := 0; i < n; i++ {
303+ uf.p[i] = i
304+ uf.size[i] = 1
305+ }
306+ return uf
307+ }
308+
309+ func (uf *UnionFind) find(x int) int {
310+ if uf.p[x] != x {
311+ uf.p[x] = uf.find(uf.p[x])
312+ }
313+ return uf.p[x]
314+ }
315+
316+ func (uf *UnionFind) union(a, b int) bool {
317+ pa := uf.find(a)
318+ pb := uf.find(b)
319+ if pa == pb {
320+ return false
321+ }
322+
323+ if uf.size[pa] > uf.size[pb] {
324+ uf.p[pb] = pa
325+ uf.size[pa] += uf.size[pb]
326+ } else {
327+ uf.p[pa] = pb
328+ uf.size[pb] += uf.size[pa]
329+ }
330+ return true
331+ }
332+
333+ func minTime(n int, edges [][]int, k int) int {
334+ sort.Slice(edges, func(i, j int) bool {
335+ return edges[i][2] < edges[j][2]
336+ })
337+
338+ uf := NewUnionFind(n)
339+ cnt := n
340+
341+ for i := len(edges) - 1; i >= 0; i-- {
342+ u := edges[i][0]
343+ v := edges[i][1]
344+ t := edges[i][2]
345+
346+ if uf.union(u, v) {
347+ cnt--
348+ if cnt < k {
349+ return t
350+ }
351+ }
352+ }
353+ return 0
354+ }
355+ ```
135356
357+ #### TypeScript
358+
359+ ``` ts
360+ class UnionFind {
361+ p: number [];
362+ size: number [];
363+
364+ constructor (n : number ) {
365+ this .p = Array .from ({ length: n }, (_ , i ) => i );
366+ this .size = Array (n ).fill (1 );
367+ }
368+
369+ find(x : number ): number {
370+ if (this .p [x ] !== x ) {
371+ this .p [x ] = this .find (this .p [x ]);
372+ }
373+ return this .p [x ];
374+ }
375+
376+ union(a : number , b : number ): boolean {
377+ const pa = this .find (a );
378+ const pb = this .find (b );
379+ if (pa === pb ) return false ;
380+
381+ if (this .size [pa ] > this .size [pb ]) {
382+ this .p [pb ] = pa ;
383+ this .size [pa ] += this .size [pb ];
384+ } else {
385+ this .p [pa ] = pb ;
386+ this .size [pb ] += this .size [pa ];
387+ }
388+ return true ;
389+ }
390+ }
391+
392+ function minTime(n : number , edges : number [][], k : number ): number {
393+ edges .sort ((a , b ) => a [2 ] - b [2 ]);
394+
395+ const uf = new UnionFind (n );
396+ let cnt = n ;
397+
398+ for (let i = edges .length - 1 ; i >= 0 ; i -- ) {
399+ const [u, v, t] = edges [i ];
400+
401+ if (uf .union (u , v )) {
402+ if (-- cnt < k ) {
403+ return t ;
404+ }
405+ }
406+ }
407+
408+ return 0 ;
409+ }
136410```
137411
138412<!-- tabs:end -->
0 commit comments