当前位置:   article > 正文

代码随想录Day69(图论Part05)

代码随想录Day69(图论Part05)

并查集

  1. // 1.初始化
  2. int fa[MAXN];
  3. void init(int n)
  4. {
  5. for (int i=1;i<=n;++i)
  6. fa[i]=i;
  7. }
  8. // 2.查询
  9. 找到的祖先直接返回,未进行路径压缩
  10. int.find(int i){
  11. if(fa[i] == i)
  12. return i;// 递归出口,当到达了祖先位置,就返回祖先
  13. else
  14. return find(fa[i]);// 不断往上查找祖先
  15. }
  16. // 3.合并
  17. void unionn(int i,int j)
  18. int i_fa=find(i);// 找到i的祖先
  19. int j_fa=find(j);// 找到j的祖先
  20. fa[i_fa]=j_fa;// i的祖先指向j的祖先。
  21. }

路径压缩,也就是在某一次find函数执行过程中,更新子节点的指向,直接指向顶级节点

107.寻找存在的路径

题目:107. 寻找存在的路径 (kamacoder.com)

思路:难道说,使用并查集的find函数,遍历所有的边,将节点的父亲信息存起来,如果source和destination没有指向同一个根节点,那么就说明不存在路径

尝试(不对)
  1. import java.util.*;
  2. class Main{
  3. public static int n;
  4. public static int m;
  5. public static int[] fa;
  6. public static void main(String[] args){
  7. Scanner scanner = new Scanner(System.in);
  8. n = scanner.nextInt();
  9. m = scanner.nextInt();
  10. fa = new int[n];
  11. for(int i = 0; i<n; i++){
  12. fa[i] = i;
  13. }
  14. for(int i = 0; i<m; i++){
  15. int n1 = scanner.nextInt();
  16. int n2 = scanner.nextInt();
  17. union(n1,n2);
  18. }
  19. int source = scanner.nextInt();
  20. int destination = scanner.nextInt();
  21. if(source == find(destination)){
  22. System.out.println(1);
  23. }else{
  24. System.out.println(0);
  25. }
  26. }
  27. public static void union(int i , int j){
  28. int i_fa = find(i);
  29. int j_fa = find(j);
  30. fa[i_fa] = j_fa;
  31. }
  32. public static int find(int j){
  33. if(j==fa[j])
  34. return j;
  35. else{
  36. fa[j] = find(fa[j]);
  37. return fa[j];
  38. }
  39. }
  40. }
答案
  1. import java.util.Scanner;
  2. public class Main {
  3. private static int[] father;
  4. public static void main(String[] args) {
  5. Scanner scanner = new Scanner(System.in);
  6. int n = scanner.nextInt(); // 节点数量
  7. int m = scanner.nextInt(); // 边的数量
  8. // 初始化并查集
  9. father = new int[n + 1];
  10. init(n);
  11. // 读取边并构建并查集
  12. for (int i = 0; i < m; i++) {
  13. int s = scanner.nextInt();
  14. int t = scanner.nextInt();
  15. join(s, t);
  16. }
  17. int source = scanner.nextInt(); // 起始节点
  18. int destination = scanner.nextInt(); // 目标节点
  19. // 判断是否在同一个集合中
  20. if (isSame(source, destination)) {
  21. System.out.println(1);
  22. } else {
  23. System.out.println(0);
  24. }
  25. }
  26. // 并查集初始化
  27. private static void init(int n) {
  28. for (int i = 1; i <= n; i++) {
  29. father[i] = i;
  30. }
  31. }
  32. // 并查集里寻根的过程
  33. private static int find(int u) {
  34. if (u != father[u]) {
  35. father[u] = find(father[u]);
  36. }
  37. return father[u];
  38. }
  39. // 判断 u 和 v 是否找到同一个根
  40. private static boolean isSame(int u, int v) {
  41. return find(u) == find(v);
  42. }
  43. // 将 v -> u 这条边加入并查集
  44. private static void join(int u, int v) {
  45. int rootU = find(u);
  46. int rootV = find(v);
  47. if (rootU != rootV) {
  48. father[rootV] = rootU;
  49. }
  50. }
  51. }
小结

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/804926
推荐阅读
相关标签
  

闽ICP备14008679号