1#![feature(let_chains)]
4
5struct Sol684;
7
8impl Sol684 {
9 pub fn find_redundant_connection(edges: Vec<Vec<i32>>) -> Vec<i32> {
10 println!("* {:?}", edges);
11
12 #[derive(Debug)]
13 struct DJSet {
14 parent: Vec<usize>,
15 rank: Vec<usize>,
16 }
17
18 impl DJSet {
19 fn new(count: usize) -> Self {
20 DJSet {
21 parent: Vec::from_iter(0..=count),
22 rank: vec![0; count + 1],
23 }
24 }
25
26 fn find(&mut self, v: usize) -> usize {
27 if v != self.parent[v] {
28 self.parent[v] = self.find(self.parent[v]);
29 }
30 self.parent[v]
31 }
32
33 fn union(&mut self, u: usize, v: usize) -> bool {
34 let (u, v) = (self.find(u), self.find(v));
35 match u == v {
36 true => false,
37 false => {
38 match self.rank[u] > self.rank[v] {
39 true => self.parent[v] = u,
40 _ => {
41 self.parent[u] = v;
42 if self.rank[v] == self.rank[u] {
43 self.rank[v] += 1;
44 }
45 }
46 }
47 true
48 }
49 }
50 }
51 }
52
53 let mut djset = DJSet::new(edges.len());
54 for edge in edges {
55 println!("-> {:?} ~ {:?}", edge, djset);
56
57 if !djset.union(edge[0] as usize, edge[1] as usize) {
58 return vec![edge[0], edge[1]];
59 }
60 }
61
62 vec![]
63 }
64
65 fn find_redundant_connection_graph(edges: Vec<Vec<i32>>) -> Vec<i32> {
66 println!("* {:?}", edges);
67
68 let mut graph = vec![vec![]; edges.len() + 1];
69 for e in &edges {
70 graph[e[0] as usize].push(e[1] as usize);
71 graph[e[1] as usize].push(e[0] as usize);
72 }
73
74 println!("-> {:?}", graph);
75
76 let mut visited = vec![false; edges.len() + 1];
77 let mut prv = vec![0; edges.len() + 1];
78 let mut icycle = 0; let mut q = vec![1];
81
82 while let Some(v) = q.pop() {
83 visited[v] = true;
84
85 graph[v].iter().for_each(|&u| {
86 match visited[u] {
87 false => {
88 prv[u] = v;
89 q.push(u);
90 }
91 true => {
92 if prv[v] != u && icycle == 0 {
93 icycle = u; prv[u] = v;
95 }
96 }
97 }
98 });
99 }
100
101 println!("-> {:?}", prv);
102
103 let mut cnodes = vec![false; edges.len() + 1];
104 while !cnodes[icycle] {
105 cnodes[icycle] = true;
106 icycle = prv[icycle];
107 }
108
109 println!("-> {:?}", cnodes);
110
111 edges
112 .iter()
113 .rev()
114 .skip_while(|&v| !cnodes[v[0] as usize] || !cnodes[v[1] as usize])
115 .take(1)
116 .fold(vec![], |_, v| v.clone())
117 }
118}
119
120struct Sol695;
122
123impl Sol695 {
124 pub fn max_area_of_island(grid: Vec<Vec<i32>>) -> i32 {
125 fn island(grid: &mut Vec<Vec<i32>>, r: usize, c: usize) -> i32 {
126 println!("-> @ {:?} ~ {}", (r, c), grid[r][c]);
127
128 match grid[r][c] {
129 0 => 0,
130 _ => {
131 grid[r][c] = 0;
132
133 let mut area = 1;
134 if r > 0 {
135 area += island(grid, r - 1, c);
136 }
137 if r + 1 < grid.len() {
138 area += island(grid, r + 1, c);
139 }
140 if c > 0 {
141 area += island(grid, r, c - 1);
142 }
143 if c + 1 < grid[r].len() {
144 area += island(grid, r, c + 1);
145 }
146 area
147 }
148 }
149 }
150
151 let mut grid = grid;
152
153 let mut xarea = 0;
154 for r in 0..grid.len() {
155 for c in 0..grid[0].len() {
156 xarea = xarea.max(island(&mut grid, r, c));
157 }
158 }
159
160 println!(":: {}", xarea);
161
162 xarea
163 }
164}
165
166struct Sol753 {}
168impl Sol753 {
169 pub fn crack_safe(n: i32, k: i32) -> String {
170 use std::collections::HashSet;
171
172 fn dfs(v: String, k: usize, euler_path: &mut Vec<char>, visited: &mut HashSet<String>) {
173 for chr in ('0'..='9').take(k) {
174 let mut u: String = v.chars().collect();
175 u.push(chr);
176
177 if !visited.contains(&u) {
178 visited.insert(u.clone());
179 dfs(u.chars().skip(1).collect(), k, euler_path, visited);
180
181 euler_path.push(chr);
182 }
183 }
184 }
185
186 let mut visited: HashSet<String> = HashSet::new();
187 let mut euler_path: Vec<char> = vec![];
188
189 dfs(
190 vec!['0'; n as usize - 1].iter().collect(),
191 k as usize,
192 &mut euler_path,
193 &mut visited,
194 );
195
196 (0..n - 1).for_each(|_| euler_path.push('0'));
197
198 println!("-> {visited:?}");
199
200 euler_path.iter().collect()
201 }
202}
203
204struct Sol802;
206
207impl Sol802 {
208 pub fn eventual_safe_nodes(graph: Vec<Vec<i32>>) -> Vec<i32> {
209 let n = graph.len();
210
211 let (mut rvs, mut ins) = (vec![vec![]; n], vec![0; n]);
212 (0..n).for_each(|v| {
213 graph[v].iter().for_each(|&u| {
214 ins[v] += 1;
215 rvs[u as usize].push(v);
216 });
217 });
218
219 println!(" -> {:?} -> {:?}", graph, rvs);
220 println!(" -> {:?}", ins);
221
222 let mut q: Vec<_> = ins
223 .iter()
224 .enumerate()
225 .filter_map(|(v, °ree)| if degree == 0 { Some(v) } else { None })
226 .collect();
227
228 let mut rst = vec![false; n];
229 while let Some(v) = q.pop() {
230 rst[v] = true;
231
232 for u in rvs[v].iter().cloned() {
233 ins[u] -= 1;
234 if ins[u] == 0 {
235 q.push(u);
236 }
237 }
238 }
239
240 rst.iter()
241 .enumerate()
242 .filter_map(|(v, &flag)| if flag { Some(v as i32) } else { None })
243 .collect()
244 }
245}
246
247struct Sol827;
249
250impl Sol827 {
251 pub fn largest_island(grid: Vec<Vec<i32>>) -> i32 {
252 let mut grid = grid;
253 let (rows, cols) = (grid.len(), grid[0].len());
254 let dirs = [-1, 0, 1, 0, -1];
255
256 let mut areas = vec![0, 0];
257 let mut islands = 0;
258 for r in 0..rows {
259 for c in 0..cols {
260 if grid[r][c] == 1 {
261 let mut area = 0;
262
263 let mut q = Vec::from([(r, c)]);
264 while let Some((r, c)) = q.pop() {
265 if grid[r][c] != 1 {
266 continue;
267 }
268
269 area += 1;
270 grid[r][c] = 2 + islands;
271
272 for i in 0..4 {
273 let (r, c) = (
274 r.wrapping_add_signed(dirs[i]),
275 c.wrapping_add_signed(dirs[i + 1]),
276 );
277 if r < rows && c < cols {
278 q.push((r, c));
279 }
280 }
281 }
282
283 areas.push(area);
284 islands += 1;
285 }
286 }
287 }
288
289 println!("-> Grid: {grid:?}");
290 println!("-> Island Areas: {areas:?}");
291
292 use std::collections::HashSet;
293
294 let mut xarea = 0;
295 for r in 0..rows {
296 for c in 0..cols {
297 if grid[r][c] == 0 {
298 let mut iset = HashSet::new();
299 for i in 0..4 {
300 let (r, c) = (
301 r.wrapping_add_signed(dirs[i]),
302 c.wrapping_add_signed(dirs[i + 1]),
303 );
304 if r < rows && c < cols {
305 iset.insert(grid[r][c]);
306 }
307 }
308 xarea = xarea.max(iset.iter().fold(0, |r, &v| r + areas[v as usize]) + 1);
309 }
310 }
311 }
312
313 match islands {
314 0 => 1,
315 1 if areas[2] as usize == rows * cols => areas[2],
316 _ => xarea,
317 }
318 }
319}
320
321struct Sol909 {}
323
324impl Sol909 {
325 pub fn snakes_and_ladders(board: Vec<Vec<i32>>) -> i32 {
327 use std::collections::VecDeque;
328
329 let n = board.len();
330 let barray: Vec<i32> = board
331 .into_iter()
332 .rev()
333 .enumerate()
334 .flat_map(|(i, row)| {
335 if i & 1 == 0 {
336 row
337 } else {
338 row.into_iter().rev().collect()
339 }
340 })
341 .collect();
342
343 println!("-> Boustrophedon :: {barray:?}");
344
345 let mut dists = vec![i32::MAX; n * n];
346
347 let mut queue = VecDeque::from([0]);
348 dists[0] = 0;
349 while let Some(v) = queue.pop_front() {
350 println!("-> {v:>2} {queue:?}");
351
352 if v == n * n - 1 {
353 continue;
354 }
355
356 for (mut u, &jump) in barray
357 .iter()
358 .enumerate()
359 .take((v + 7).min(n * n))
360 .skip(v + 1)
361 {
362 if jump != -1 {
363 u = jump as usize - 1;
364 }
365
366 if dists[u] > dists[v] + 1 {
367 dists[u] = dists[v] + 1;
368 queue.push_back(u);
369 }
370 }
371 }
372
373 println!("-> Distances :: {dists:?}");
374
375 if dists[n * n - 1] == i32::MAX {
376 return -1;
377 }
378 dists[n * n - 1]
379 }
380}
381
382struct Sol1267;
384
385impl Sol1267 {
386 pub fn count_servers(grid: Vec<Vec<i32>>) -> i32 {
387 let (rows, cols) = (grid.len(), grid[0].len());
388
389 let rn: Vec<_> = (0..rows)
390 .map(|r| (0..cols).filter(|&c| grid[r][c] == 1).count())
391 .collect();
392 let cn: Vec<_> = (0..cols)
393 .map(|c| (0..rows).filter(|&r| grid[r][c] == 1).count())
394 .collect();
395
396 println!(" -> R: {:?} C: {:?}", rn, cn);
397
398 (0..rows)
399 .flat_map(|r| (0..cols).map(move |c| (r, c)))
400 .filter(|&(r, c)| rn[r] > 1 || cn[c] > 1)
401 .map(|(r, c)| grid[r][c])
402 .sum()
403 }
404}
405
406struct Sol1298 {}
408
409impl Sol1298 {
410 pub fn max_candies(
411 status: Vec<i32>,
412 candies: Vec<i32>,
413 keys: Vec<Vec<i32>>,
414 contained_boxes: Vec<Vec<i32>>,
415 initial_boxes: Vec<i32>,
416 ) -> i32 {
417 let mut gots = vec![false; status.len()];
418 let mut opened = vec![false; status.len()];
419 let mut can_open: Vec<_> = status.iter().map(|&v| v == 1).collect();
420
421 use std::collections::VecDeque;
422
423 let mut queue = VecDeque::new();
424 for ibox in initial_boxes.iter().map(|&v| v as usize) {
425 gots[ibox] = true;
426 if can_open[ibox] {
427 queue.push_back(ibox);
428 opened[ibox] = true;
429 }
430 }
431
432 let mut total = 0;
433 while let Some(qbox) = queue.pop_front() {
434 total += candies[qbox];
435
436 for kbox in keys[qbox].iter().map(|&v| v as usize) {
437 can_open[kbox] = true;
438 if gots[kbox] && !opened[kbox] {
439 queue.push_back(kbox);
440 opened[kbox] = true;
441 }
442 }
443
444 for gbox in contained_boxes[qbox].iter().map(|&v| v as usize) {
445 gots[gbox] = true;
446 if can_open[gbox] && !opened[gbox] {
447 queue.push_back(gbox);
448 opened[gbox] = true;
449 }
450 }
451 }
452
453 total
454 }
455}
456
457struct Sol1368;
459
460impl Sol1368 {
461 pub fn min_cost(grid: Vec<Vec<i32>>) -> i32 {
462 use std::cmp::Reverse;
463 use std::collections::BinaryHeap;
464
465 let (rows, cols) = (grid.len(), grid[0].len());
466 let mut costs = vec![vec![i32::MAX; cols]; rows];
467
468 let mut pq = BinaryHeap::new();
469 pq.push(Reverse((0, 0i32, 0i32)));
470 costs[0][0] = 0;
471
472 println!(" -> {:?}", pq);
473 while let Some(Reverse((w, r, c))) = pq.pop() {
474 if costs[r as usize][c as usize] < w {
475 continue;
476 }
477
478 print!(" -> {:?} :: ", (w, r, c));
479
480 [(0, 1), (0, -1), (1, 0), (-1, 0)]
481 .into_iter()
482 .zip(1..=4)
483 .inspect(|o| print!(" {:?}", o))
484 .for_each(|((dx, dy), dir)| {
485 let w = w + (dir != grid[r as usize][c as usize]) as i32;
486 let (r, c) = (r + dx, c + dy);
487 if 0 <= r
488 && r < rows as i32
489 && 0 <= c
490 && c < cols as i32
491 && w < costs[r as usize][c as usize]
492 {
493 costs[r as usize][c as usize] = w;
494 pq.push(Reverse((w, r, c)));
495 }
496 });
497
498 println!();
499 println!(" -> {:?}", pq);
500 }
501
502 println!(" :: {}", costs[rows - 1][cols - 1]);
503
504 costs[rows - 1][cols - 1]
505 }
506
507 fn min_cost_bfs01(grid: Vec<Vec<i32>>) -> i32 {
508 use std::collections::VecDeque;
509
510 let (rows, cols) = (grid.len(), grid[0].len());
511 let mut costs = vec![vec![i32::MAX; cols]; rows];
512
513 let mut q = VecDeque::new();
514
515 q.push_front((0i32, 0i32));
516 costs[0][0] = 0;
517
518 println!(" -> {:?}", q);
519
520 while let Some((r, c)) = q.pop_front() {
521 let curw = costs[r as usize][c as usize];
522
523 [(0, 1), (0, -1), (1, 0), (-1, 0)]
524 .into_iter()
525 .zip(1..=4)
526 .for_each(|((dx, dy), dir)| {
527 let w = (grid[r as usize][c as usize] != dir) as i32;
528 let (r, c) = (r + dx, c + dy);
529 if 0 <= r
530 && r < rows as i32
531 && 0 <= c
532 && c < cols as i32
533 && curw + w < costs[r as usize][c as usize]
534 {
535 costs[r as usize][c as usize] = curw + w;
536 match w {
537 0 => q.push_front((r, c)),
538 _ => q.push_back((r, c)),
539 }
540 }
541 });
542
543 println!(" -> {:?}", q);
544 }
545
546 println!(" :: {}", costs[rows - 1][cols - 1]);
547
548 costs[rows - 1][cols - 1]
549 }
550}
551
552struct Sol1462;
554
555impl Sol1462 {
556 pub fn check_if_prerequisite(
557 num_courses: i32,
558 prerequisites: Vec<Vec<i32>>,
559 queries: Vec<Vec<i32>>,
560 ) -> Vec<bool> {
561 let mut graph = vec![vec![]; num_courses as usize];
562
563 prerequisites.iter().for_each(|v| {
564 graph[v[0] as usize].push(v[1] as usize);
565 });
566
567 println!(" -> {:?}", graph);
568
569 let mut floyd_warshall = vec![vec![false; num_courses as usize]; num_courses as usize];
570 prerequisites.iter().for_each(|v| {
571 floyd_warshall[v[0] as usize][v[1] as usize] = true;
572 });
573 (0..num_courses as usize).for_each(|v| floyd_warshall[v][v] = true);
574
575 (0..num_courses as usize).for_each(|src| {
576 (0..num_courses as usize).for_each(|dst| {
577 (0..num_courses as usize).for_each(|via| {
578 floyd_warshall[src][dst] |=
579 floyd_warshall[src][via] && floyd_warshall[via][dst];
580 })
581 })
582 });
583
584 println!(" -> {:?}", floyd_warshall);
585
586 let mut memory = vec![vec![false; num_courses as usize]; num_courses as usize];
587
588 (0..num_courses as usize).for_each(|src| {
589 let mut q = vec![];
590 q.push(src);
591
592 while let Some(v) = q.pop() {
593 memory[src][v] = true;
594 graph[v].iter().for_each(|&u| {
595 if !memory[src][u] {
596 q.push(u)
597 }
598 });
599 }
600 });
601
602 assert_eq!(memory, floyd_warshall);
603
604 queries.into_iter().fold(vec![], |mut rst, qry| {
605 rst.push(memory[qry[0] as usize][qry[1] as usize]);
606 rst
607 })
608 }
609}
610
611struct Sol1765;
613
614impl Sol1765 {
615 pub fn highest_peak(is_water: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
616 use std::collections::VecDeque;
617
618 let (rows, cols) = (is_water.len(), is_water[0].len());
619 let mut q = VecDeque::new();
620 let mut visited = vec![vec![false; cols]; rows];
621
622 (0..rows).for_each(|r| {
623 (0..cols).for_each(|c| {
624 if is_water[r][c] == 1 {
625 q.push_back((r as i32, c as i32, 0));
626 visited[r][c] = true;
627 }
628 })
629 });
630
631 let mut rst = vec![vec![0; cols]; rows];
632 let dirs = [-1, 0, 1, 0, -1];
633
634 println!(" -> {:?}", q);
635 while let Some((r, c, h)) = q.pop_front() {
636 println!(" -> {:?}", q);
637
638 (0..4).for_each(|i| {
639 let (x, y) = (r + dirs[i], c + dirs[i + 1]);
640 if 0 <= x
641 && x < rows as i32
642 && 0 <= y
643 && y < cols as i32
644 && !visited[x as usize][y as usize]
645 {
646 visited[x as usize][y as usize] = true;
647 rst[x as usize][y as usize] = h + 1;
648 q.push_back((x, y, h + 1));
649 }
650 });
651 }
652
653 rst
654 }
655}
656
657struct Sol1976;
659
660impl Sol1976 {
661 pub fn count_paths(n: i32, roads: Vec<Vec<i32>>) -> i32 {
665 let n = n as usize;
666 const M: u64 = 1e9 as u64 + 7;
667
668 let mut graph = vec![vec![(1e9 as u64 * 200 + 1, 0); n]; n];
670 for road in roads {
671 let (u, v, t) = (road[0] as usize, road[1] as usize, road[2] as u64);
672 graph[u][v] = (t, 1);
673 graph[v][u] = (t, 1);
674 }
675
676 for (i, vc) in graph.iter_mut().enumerate() {
677 vc[i] = (0u64, 1);
678 }
679
680 use std::cmp::Ordering::*;
681
682 for m in 0..n {
684 for v in 0..n {
685 for u in 0..n {
686 if v != m && u != m {
687 match (graph[u][m].0 + graph[m][v].0).cmp(&graph[u][v].0) {
688 Less => {
689 graph[u][v].0 = graph[u][m].0 + graph[m][v].0;
690 graph[u][v].1 = (graph[u][m].1 * graph[m][v].1) % M;
691 }
692 Equal => {
693 graph[u][v].1 += (graph[u][m].1 * graph[m][v].1) % M;
694 graph[u][v].1 %= M;
695 }
696 _ => {}
697 }
698 }
699 }
700 }
701 }
702
703 println!("-> {:?}", graph);
704
705 graph[0][n - 1].1 as i32
706 }
707}
708
709struct Sol2127;
711
712impl Sol2127 {
713 pub fn maximum_invitations(favorite: Vec<i32>) -> i32 {
714 use std::collections::VecDeque;
715
716 let n = favorite.len();
717 let mut ins = vec![0; n];
718 favorite.iter().for_each(|&f| ins[f as usize] += 1);
719
720 let mut q = VecDeque::from(
721 ins.iter()
722 .enumerate()
723 .filter_map(|(v, °ree)| if degree == 0 { Some(v) } else { None })
724 .collect::<Vec<_>>(),
725 );
726
727 let mut depth = vec![1; n];
728
729 while let Some(v) = q.pop_front() {
730 let u = favorite[v] as usize;
731
732 depth[u] = depth[u].max(depth[v] + 1);
733 ins[u] -= 1;
734 if ins[u] == 0 {
735 q.push_back(u);
736 }
737 }
738
739 let (mut lcycle, mut tcycle) = (0, 0);
740 (0..n).for_each(|v| {
741 if ins[v] != 0 {
742 let (mut l, mut cur) = (0, v);
743 while ins[cur] > 0 {
744 ins[cur] = 0;
745 l += 1;
746 cur = favorite[cur] as usize;
747 }
748
749 match l {
750 2 => tcycle += depth[v] + depth[favorite[v] as usize],
751 _ => lcycle = lcycle.max(l),
752 }
753 }
754 });
755
756 println!(" :: {:?}", (lcycle, tcycle));
757
758 lcycle.max(tcycle)
759 }
760}
761
762struct Sol2359 {}
764
765impl Sol2359 {
766 pub fn closest_meeting_node(edges: Vec<i32>, node1: i32, node2: i32) -> i32 {
768 fn dfs(v: usize, dists: &mut [i32], edges: &[i32]) {
769 let u = edges[v];
770 if u != -1 && dists[u as usize] == i32::MAX {
771 dists[u as usize] = dists[v] + 1;
772 dfs(u as usize, dists, edges);
773 }
774 }
775
776 fn bfs(src: usize, dists: &mut [i32], edges: &[i32]) {
777 use std::collections::VecDeque;
778
779 let mut queue = VecDeque::from([src]);
780 dists[src] = 0;
781
782 while let Some(v) = queue.pop_front() {
783 let u = edges[v];
784 if u != -1 && dists[u as usize] == i32::MAX {
785 dists[u as usize] = dists[v] + 1;
786 queue.push_back(u as usize);
787 }
788 }
789 }
790
791 let (mut dists1, mut dists2) = (vec![i32::MAX; edges.len()], vec![i32::MAX; edges.len()]);
792 (dists1[node1 as usize], dists2[node2 as usize]) = (0, 0);
793
794 dfs(node1 as usize, &mut dists1, &edges);
795 println!("-> {node1} ~ {dists1:?}");
796
797 bfs(node2 as usize, &mut dists2, &edges);
798 println!("-> {node2} ~ {dists2:?}");
799
800 (0..edges.len())
801 .fold((-1, i32::MAX), |(m_node, m_dist), v| {
802 if m_dist > dists1[v].max(dists2[v]) {
803 (v as i32, dists1[v].max(dists2[v]))
804 } else {
805 (m_node, m_dist)
806 }
807 })
808 .0
809 }
810}
811
812struct Sol2467;
814
815impl Sol2467 {
816 pub fn most_profitable_path(edges: Vec<Vec<i32>>, bob: i32, amount: Vec<i32>) -> i32 {
817 let n = edges.len() + 1;
818 let mut graph = vec![vec![]; n];
819
820 for e in edges {
821 graph[e[0] as usize].push(e[1] as usize);
822 graph[e[1] as usize].push(e[0] as usize);
823 }
824
825 println!("-> {:?}", graph);
826
827 let mut bdist = vec![100_000; n];
828 bdist[bob as usize] = 0;
829
830 fn search(
831 u: usize,
832 p: usize,
833 time: usize,
834 graph: &Vec<Vec<usize>>,
835 bdist: &mut Vec<usize>,
836 amount: &Vec<i32>,
837 ) -> i32 {
838 let mut profit = 0;
839 let mut neighbors = i32::MIN;
840
841 for &v in &graph[u] {
842 if v != p {
843 neighbors = neighbors.max(search(v, u, time + 1, graph, bdist, amount));
844 bdist[u] = bdist[u].min(bdist[v] + 1);
845 }
846 }
847
848 use std::cmp::Ordering::*;
849 profit += match bdist[u].cmp(&time) {
850 Greater => amount[u],
851 Equal => amount[u] / 2,
852 _ => 0,
853 };
854
855 match neighbors {
856 i32::MIN => profit,
857 _ => profit + neighbors,
858 }
859 }
860
861 search(0, n, 0, &graph, &mut bdist, &amount)
862 }
863}
864
865struct Sol2493;
867
868impl Sol2493 {
869 pub fn magnificent_sets(n: i32, edges: Vec<Vec<i32>>) -> i32 {
870 use std::collections::VecDeque;
871
872 println!("* {:?}", edges);
873
874 let mut graph = vec![vec![]; n as usize + 1];
875 for e in &edges {
876 graph[e[0] as usize].push(e[1] as usize);
877 graph[e[1] as usize].push(e[0] as usize);
878 }
879 println!("-> graph :: {:?}", graph);
880
881 let mut bicolors = vec![-1; graph.len()];
882 for v in 1..graph.len() {
883 if bicolors[v] != -1 {
884 continue;
885 }
886
887 bicolors[v] = 0;
888 let mut q = vec![v];
889
890 while let Some(v) = q.pop() {
891 println!("-> {} {:?}", v, q);
892
893 for &u in &graph[v] {
894 if bicolors[u] == bicolors[v] {
895 return -1; }
897 if bicolors[u] != -1 {
898 continue;
899 }
900
901 bicolors[u] = bicolors[v] ^ 1;
902 q.push(u);
903 }
904 }
905 }
906 println!("-> colors :: {:?}", bicolors);
907
908 let mut dist = vec![0; graph.len()];
909 for n in 1..graph.len() {
910 let mut dq = VecDeque::new();
911 let mut visited = vec![false; graph.len()];
912
913 dq.push_back(n);
914 visited[n] = true;
915
916 let mut xdist = 0;
917 while !dq.is_empty() {
918 for _ in 0..dq.len() {
919 if let Some(v) = dq.pop_front() {
920 for &u in &graph[v] {
921 if !visited[u] {
922 visited[u] = true;
923 dq.push_back(u);
924 }
925 }
926 }
927 }
928 xdist += 1;
929 }
930
931 dist[n] = xdist;
932 }
933 println!("-> distances :: {:?}", dist);
934
935 let mut groups = 0;
936 let mut visited = vec![false; graph.len()];
937 for n in 1..graph.len() {
938 if !visited[n] {
939 let mut ngroup = 0;
940 let mut q = vec![n];
941 visited[n] = true;
942 while let Some(v) = q.pop() {
943 ngroup = ngroup.max(dist[v]);
944 for &u in &graph[v] {
945 if !visited[u] {
946 visited[u] = true;
947 q.push(u);
948 }
949 }
950 }
951
952 groups += ngroup;
953 }
954 }
955
956 groups
957 }
958}
959
960struct Sol2503;
962
963impl Sol2503 {
964 pub fn max_points(grid: Vec<Vec<i32>>, queries: Vec<i32>) -> Vec<i32> {
965 use std::cmp::Reverse;
966 use std::collections::BinaryHeap;
967
968 let mut sqry = vec![];
969 for (i, &qry) in queries.iter().enumerate() {
970 sqry.push((qry, i));
971 }
972 sqry.sort_unstable();
973 println!("-> {:?}", sqry);
974
975 let (rows, cols) = (grid.len(), grid[0].len());
976 let mut visited = vec![vec![false; cols]; rows];
977
978 let mut pq = BinaryHeap::new();
979
980 pq.push(Reverse((grid[0][0], 0usize, 0usize)));
981 visited[0][0] = true;
982
983 let mut rst = vec![0; queries.len()];
984 let mut points = 0;
985
986 const DIRS: [isize; 5] = [-1, 0, 1, 0, -1];
987 for (qry, i) in sqry {
988 while let Some(&Reverse((gval, r, c))) = pq.peek()
989 && gval < qry
990 {
991 println!("-> {} {:?}", gval, (r, c));
992
993 pq.pop();
994 points += 1;
995
996 for d in 0..4 {
997 let (r, c) = (
998 r.overflowing_add_signed(DIRS[d]).0,
999 c.overflowing_add_signed(DIRS[d + 1]).0,
1000 );
1001
1002 if r < rows && c < cols && !visited[r][c] {
1003 visited[r][c] = true;
1004 pq.push(Reverse((grid[r][c], r, c)));
1005
1006 println!("-> * {:?} {:?}", (r, c), &pq);
1007 }
1008 }
1009 }
1010
1011 rst[i] = points;
1012 }
1013
1014 rst
1015 }
1016}
1017
1018struct Sol2608;
1020
1021impl Sol2608 {
1022 pub fn find_shortest_cycle(n: i32, edges: Vec<Vec<i32>>) -> i32 {
1023 use std::collections::VecDeque;
1024
1025 println!("* {:?}", edges);
1026
1027 let n = n as usize;
1028 let mut graph = vec![vec![]; n];
1029 for e in &edges {
1030 let (v, u) = (e[0] as usize, e[1] as usize);
1031 graph[v].push(u);
1032 graph[u].push(v);
1033 }
1034 println!("-> graph :: {:?}", graph);
1035
1036 let mut mcycle = usize::MAX;
1037 (0..n).for_each(|src| {
1038 let mut dist = vec![usize::MAX; n];
1039
1040 let mut dq = VecDeque::new();
1041 dq.push_back(src);
1042 dist[src] = 0;
1043
1044 while let Some(v) = dq.pop_front() {
1045 println!(" -> {} {:?}", v, dq);
1046
1047 for &u in &graph[v] {
1048 match dist[u] {
1049 usize::MAX => {
1050 dist[u] = dist[v] + 1;
1051 dq.push_back(u);
1052 }
1053 _ => {
1054 if dist[v] <= dist[u] {
1055 mcycle = mcycle.min(dist[u] + dist[v] + 1);
1056 }
1057 }
1058 }
1059 }
1060 }
1061 });
1062
1063 match mcycle {
1064 usize::MAX => -1,
1065 _ => mcycle as i32,
1066 }
1067 }
1068}
1069
1070struct Sol2658;
1072
1073impl Sol2658 {
1074 pub fn find_max_fish(grid: Vec<Vec<i32>>) -> i32 {
1075 println!("* {:?}", grid);
1076
1077 let (rows, cols) = (grid.len(), grid[0].len());
1078 let mut visited = vec![vec![false; cols]; rows];
1079
1080 let dir = [-1, 0, 1, 0, -1];
1081 let mut xfish = 0;
1082
1083 (0..rows).for_each(|r| {
1084 (0..cols).for_each(|c| {
1085 if grid[r][c] != 0 && !visited[r][c] {
1086 println!("-> {:?}", (r, c));
1087
1088 let mut fish = 0;
1089 let mut q = vec![];
1090
1091 q.push((r as i32, c as i32));
1092 visited[r][c] = true;
1093
1094 while let Some((r, c)) = q.pop() {
1095 println!(" -> {:?}", (r, c));
1096
1097 fish += grid[r as usize][c as usize];
1098 xfish = xfish.max(fish);
1099
1100 (0..4).for_each(|i| {
1101 let (r, c) = (r + dir[i], c + dir[i + 1]);
1102 if 0 <= r
1103 && r < rows as i32
1104 && 0 <= c
1105 && c < cols as i32
1106 && grid[r as usize][c as usize] != 0
1107 && !visited[r as usize][c as usize]
1108 {
1109 visited[r as usize][c as usize] = true;
1110 q.push((r, c));
1111 }
1112 })
1113 }
1114 }
1115 })
1116 });
1117
1118 xfish
1119 }
1120
1121 fn find_max_fish_recursion(grid: Vec<Vec<i32>>) -> i32 {
1122 fn dfs(grid: &mut Vec<Vec<i32>>, r: usize, c: usize) -> i32 {
1123 if grid[r][c] == 0 {
1124 return 0;
1125 }
1126
1127 let mut fish = grid[r][c];
1128 grid[r][c] = 0;
1129
1130 if r > 0 {
1131 fish += dfs(grid, r - 1, c);
1132 }
1133 if r + 1 < grid.len() {
1134 fish += dfs(grid, r + 1, c);
1135 }
1136 if c > 0 {
1137 fish += dfs(grid, r, c - 1);
1138 }
1139 if c + 1 < grid[0].len() {
1140 fish += dfs(grid, r, c + 1);
1141 }
1142
1143 fish
1144 }
1145
1146 let mut grid = grid;
1147 let mut xfish = 0;
1148
1149 (0..grid.len())
1150 .for_each(|r| (0..grid[0].len()).for_each(|c| xfish = xfish.max(dfs(&mut grid, r, c))));
1151
1152 xfish
1153 }
1154}
1155
1156struct Sol2685;
1158
1159impl Sol2685 {
1160 pub fn count_complete_components(n: i32, edges: Vec<Vec<i32>>) -> i32 {
1161 let mut cliques = 0;
1162
1163 let n = n as usize;
1164 let mut graph = vec![vec![]; n];
1165
1166 for edge in edges {
1167 let (v, u) = (edge[0] as usize, edge[1] as usize);
1168 graph[v].push(u);
1169 graph[u].push(v);
1170 }
1171
1172 println!("-> {:?}", graph);
1173
1174 fn dfs(graph: &[Vec<usize>], visited: &mut [bool], v: usize) -> (usize, usize) {
1175 let (mut vertices, mut edges) = (1, 0);
1176
1177 for &u in &graph[v] {
1178 edges += 1;
1179 if !visited[u] {
1180 visited[u] = true;
1181
1182 let rst = dfs(graph, visited, u);
1183 vertices += rst.0;
1184 edges += rst.1;
1185 }
1186 }
1187
1188 (vertices, edges)
1189 }
1190
1191 let mut visited = vec![false; n];
1192 for v in 0..n {
1193 if visited[v] {
1194 continue;
1195 }
1196 visited[v] = true;
1197
1198 let (vertices, edges) = dfs(&graph, &mut visited, v);
1199 if vertices * (vertices - 1) == edges {
1200 cliques += 1;
1201 }
1202 }
1203
1204 cliques
1205 }
1206}
1207
1208struct Sol3108;
1210
1211impl Sol3108 {
1212 pub fn minimum_cost(n: i32, edges: Vec<Vec<i32>>, query: Vec<Vec<i32>>) -> Vec<i32> {
1213 use std::cmp::Ordering::*;
1214
1215 let n = n as usize;
1216 let mut djset: Vec<usize> = (0..n).collect();
1217 let mut ranks = vec![0; n];
1218 let mut weights = vec![usize::MAX; n];
1219
1220 fn find(djset: &mut [usize], x: usize) -> usize {
1221 if djset[x] != x {
1222 djset[x] = find(djset, djset[x]);
1223 }
1224 djset[x]
1225 }
1226
1227 fn union(djset: &mut [usize], ranks: &mut [usize], x: usize, y: usize) -> usize {
1228 let x = find(djset, x);
1229 let y = find(djset, y);
1230 match x.cmp(&y) {
1231 Equal => x,
1232 _ => match ranks[x].cmp(&ranks[y]) {
1233 Less => {
1234 djset[x] = y;
1235 y
1236 }
1237 _ => {
1238 djset[y] = x;
1239 if ranks[x] == ranks[y] {
1240 ranks[x] += 1;
1241 }
1242 x
1243 }
1244 },
1245 }
1246 }
1247
1248 for v in &edges {
1249 union(&mut djset, &mut ranks, v[0] as usize, v[1] as usize);
1250 }
1251
1252 for v in &edges {
1253 let r = find(&mut djset, v[0] as usize);
1254 weights[r] &= v[2] as usize;
1255 }
1256
1257 println!("-> {:?}", (&djset, &ranks, &weights));
1258
1259 let mut rst = vec![];
1260 for v in query {
1261 let (x, y) = (
1262 find(&mut djset, v[0] as usize),
1263 find(&mut djset, v[1] as usize),
1264 );
1265 match x.cmp(&y) {
1266 Equal => rst.push(weights[x] as i32),
1267 _ => rst.push(-1),
1268 }
1269 }
1270
1271 rst
1272 }
1273}
1274
1275struct Sol3341;
1277
1278impl Sol3341 {
1279 pub fn min_time_to_reach(move_time: Vec<Vec<i32>>) -> i32 {
1280 use std::cmp::Reverse;
1281 use std::collections::BinaryHeap;
1282
1283 let (rows, cols) = (move_time.len(), move_time[0].len());
1284 let mut grid = vec![vec![i32::MAX; cols]; rows];
1285 let mut pq = BinaryHeap::new();
1286
1287 grid[0][0] = 0;
1288 pq.push(Reverse((0, 0, 0)));
1289
1290 while let Some(Reverse((time, r, c))) = pq.pop() {
1291 println!("-> {:?}", (time, r, c, &pq, &grid));
1292
1293 if r == rows - 1 && c == cols - 1 {
1294 return time;
1295 }
1296
1297 let dirs = [-1, 0, 1, 0, -1];
1298 for d in 0..4 {
1299 if let (Some(r), Some(c)) = (
1300 r.checked_add_signed(dirs[d]),
1301 c.checked_add_signed(dirs[d + 1]),
1302 ) {
1303 if r < rows && c < cols && move_time[r][c].max(time) + 1 < grid[r][c] {
1304 grid[r][c] = move_time[r][c].max(time) + 1;
1305 pq.push(Reverse((grid[r][c], r, c)));
1306 }
1307 }
1308 }
1309 }
1310
1311 -1
1312 }
1313}
1314
1315struct Sol3342;
1317
1318impl Sol3342 {
1319 pub fn min_time_to_reach(move_time: Vec<Vec<i32>>) -> i32 {
1320 use std::cmp::Reverse;
1321
1322 let (rows, cols) = (move_time.len(), move_time[0].len());
1323 let mut grid = vec![vec![i32::MAX; cols]; rows]; let dirs = [-1, 0, 1, 0, -1];
1326 let mut pq = std::collections::BinaryHeap::new();
1327
1328 pq.push(Reverse((0, 0, 0, false)));
1329 grid[0][0] = 0;
1330
1331 while let Some(Reverse((time, r, c, double))) = pq.pop() {
1332 println!("-> {:?}", (time, r, c, double, &pq, &grid));
1333
1334 if r + 1 == rows && c + 1 == cols {
1335 return time;
1336 }
1337
1338 let delta = if double { 2 } else { 1 };
1339
1340 for d in 0..4 {
1341 if let (Some(r), Some(c)) = (
1342 r.checked_add_signed(dirs[d]),
1343 c.checked_add_signed(dirs[d + 1]),
1344 ) {
1345 if r < rows && c < cols && move_time[r][c].max(time) + delta < grid[r][c] {
1346 grid[r][c] = move_time[r][c].max(time) + delta;
1347 pq.push(Reverse((grid[r][c], r, c, !double)));
1348 }
1349 }
1350 }
1351 }
1352
1353 -1
1354 }
1355}
1356
1357struct Sol3372 {}
1359
1360impl Sol3372 {
1361 pub fn max_target_nodes(edges1: Vec<Vec<i32>>, edges2: Vec<Vec<i32>>, k: i32) -> Vec<i32> {
1364 let (mut tree1, mut tree2) = (
1365 vec![vec![]; edges1.len() + 1],
1366 vec![vec![]; edges2.len() + 1],
1367 );
1368
1369 let mk_adjs = |tree: &mut [Vec<usize>], edges: &[Vec<i32>]| {
1370 for edge in edges {
1371 tree[edge[0] as usize].push(edge[1] as usize);
1372 tree[edge[1] as usize].push(edge[0] as usize);
1373 }
1374 };
1375
1376 for (tree, edges) in [(&mut tree1, &edges1), (&mut tree2, &edges2)] {
1377 mk_adjs(tree, edges);
1378 println!("-> {edges:?} => {tree:?}");
1379 }
1380
1381 fn dfs(v: usize, p: usize, k: i32, tree: &[Vec<usize>], dists: &mut [i32]) {
1382 for &u in &tree[v] {
1383 if u != p {
1384 dists[u] = dists[v] + 1;
1385 if dists[u] < k {
1386 dfs(u, v, k, tree, dists);
1387 }
1388 }
1389 }
1390 }
1391
1392 let mut trgs = vec![];
1393 for src in 0..=edges2.len() {
1394 let mut dists = vec![i32::MAX; edges2.len() + 1];
1395 dists[src] = 0;
1396 dfs(src, usize::MAX, k - 1, &tree2, &mut dists);
1397 println!("-> {src} {dists:?}");
1398
1399 trgs.push(dists.iter().filter(|&&d| d <= k - 1).count());
1400 }
1401 println!("-> {trgs:?}");
1402
1403 let mut xtrgs = vec![];
1404 if let Some(&xtrg) = trgs.iter().max() {
1405 for src in 0..=edges1.len() {
1406 let mut dists = vec![i32::MAX; edges1.len() + 1];
1407 dists[src] = 0;
1408 dfs(src, usize::MAX, k, &tree1, &mut dists);
1409 println!("-> {src} {dists:?}");
1410
1411 xtrgs.push((dists.iter().filter(|&&d| d <= k).count() + xtrg) as i32);
1412 }
1413 }
1414
1415 xtrgs
1416 }
1417}
1418
1419struct Sol3373 {}
1421
1422impl Sol3373 {
1423 pub fn max_target_nodes(edges1: Vec<Vec<i32>>, edges2: Vec<Vec<i32>>) -> Vec<i32> {
1424 let (mut tree1, mut tree2) = (
1425 vec![vec![]; edges1.len() + 1],
1426 vec![vec![]; edges2.len() + 1],
1427 );
1428
1429 let mk_adjs = |tree: &mut [Vec<usize>], edges: &[Vec<i32>]| {
1430 for edge in edges {
1431 tree[edge[0] as usize].push(edge[1] as usize);
1432 tree[edge[1] as usize].push(edge[0] as usize);
1433 }
1434 };
1435
1436 for (tree, edges) in [(&mut tree1, &edges1), (&mut tree2, &edges2)] {
1437 mk_adjs(tree, edges);
1438 println!("-> {edges:?} => {tree:?}");
1439 }
1440
1441 fn color_nodes(
1442 v: usize,
1443 p: usize,
1444 depth: usize,
1445 colors: &mut [usize],
1446 tree: &[Vec<usize>],
1447 ) {
1448 colors[v] = depth & 1;
1449 for &u in &tree[v] {
1450 if u != p {
1451 color_nodes(u, v, depth + 1, colors, tree);
1452 }
1453 }
1454 }
1455
1456 fn color_nodes_iterative(colors: &mut [usize], tree: &[Vec<usize>]) {
1457 use std::collections::VecDeque;
1458
1459 let mut q_bfs = VecDeque::from([(0, usize::MAX, 0)]);
1460 while let Some((v, p, depth)) = q_bfs.pop_front() {
1461 colors[v] = depth & 1;
1462 for &u in &tree[v] {
1463 if u != p {
1464 q_bfs.push_back((u, v, depth + 1));
1465 }
1466 }
1467 }
1468 }
1469
1470 let mut colors1 = vec![0; tree1.len()];
1471 color_nodes(0, usize::MAX, 0, &mut colors1, &tree1);
1472
1473 let mut counts1 = [0; 2];
1474 counts1[0] = colors1.iter().filter(|&&color| color == 0).count();
1475 counts1[1] = tree1.len() - counts1[0];
1476
1477 println!("-> {counts1:?} {colors1:?}");
1478
1479 let mut colors2 = vec![0; tree2.len()];
1480 color_nodes_iterative(&mut colors2, &tree2);
1481
1482 let mut counts2 = [0; 2];
1483 counts2[0] = colors2.iter().filter(|&&color| color == 0).count();
1484 counts2[1] = tree2.len() - counts2[0];
1485
1486 println!("-> {counts2:?} {colors2:?}");
1487
1488 let mut xtrgs = vec![];
1489 for color in colors1 {
1490 xtrgs.push((counts1[color] + counts2[0].max(counts2[1])) as i32);
1491 }
1492
1493 xtrgs
1494 }
1495}
1496
1497#[cfg(test)]
1498mod tests;