• 【基础算法 3.3】树与图的DFS和BFS(完结)


    目录

    一、846 树的重心

    二、847 图中点的层次


    DFS模板

    1. // 需要标记数组st[N],遍历节点的每个相邻的边
    2. void dfs(int u)
    3. {
    4. st[u] = true; // 标记一下,记录为已经被搜索过了,下面进行搜索过程
    5. for (int i = h[u]; i != -1; i = ne[i])
    6. {
    7. int j = e[i];
    8. if (!st[j])
    9. dfs(j);
    10. }
    11. }

    BFS模板

    1. void bfs()
    2. {
    3. int hh=0,tt=0;
    4. q[++tt]=x; //第一个点入队
    5. while(hh!=tt)
    6. {
    7. auto t=q[hh++]; //取队头元素+出队
    8. for() //遍历更新
    9. if() //如果未遍历
    10. {
    11. //状态更新
    12. q[++tt]=y; //入队
    13. }
    14. }
    15. }

    一、846 树的重心

    活动 - AcWing

    给定一颗树,树中包含 n 个结点(编号 1∼n)和 n−1 条无向边。

    请你找到树的重心,并输出将重心删除后,剩余各个连通块中点数的最大值。

    重心定义:重心是指树中的一个结点,如果将这个点删除后,剩余各个连通块中点数的最大值最小,那么这个节点被称为树的重心。

    输入格式

    第一行包含整数 n,表示树的结点数。

    接下来 n−1 行,每行包含两个整数 a 和 b,表示点 a 和点 b 之间存在一条边。

    输出格式

    输出一个整数 m,表示将重心删除后,剩余各个连通块中点数的最大值。

    数据范围

    1≤n≤105

    输入样例

    1. 9
    2. 1 2
    3. 1 7
    4. 1 4
    5. 2 8
    6. 2 5
    7. 4 3
    8. 3 9
    9. 4 6

    输出样例:

    4
    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int N = 1e5+10, M = N*2;
    7. int n;
    8. int h[N], e[M], ne[M], idx;
    9. int ans = N; //ans是取每个连通块最大值的最小值
    10. bool st[N];
    11. void add(int a, int b)
    12. {
    13. e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
    14. }
    15. //返回以u为根的子树中点的数量
    16. int dfs(int u)
    17. {
    18. st[u] = true;
    19. int size = 0, sum = 1; //sum统计该节点以下所有连通图的点数总个数 size是每个连通块的最大值
    20. for (int i = h[u]; i != -1; i = ne[i])
    21. {
    22. int j = e[i];
    23. if (!st[j])
    24. {
    25. int s = dfs(j); //s是当前子树的大小
    26. size = max(size, s);
    27. sum += s;
    28. }
    29. }
    30. size = max(size, n - sum); //再把剩下的取个max
    31. ans = min(ans, size); //ans是取每个连通块最大值的最小值
    32. return sum;
    33. }
    34. int main()
    35. {
    36. scanf("%d", &n);
    37. memset(h, -1, sizeof h);
    38. for (int i = 0; i < n - 1; i ++ )
    39. {
    40. int a, b;
    41. scanf("%d%d", &a, &b);
    42. add(a, b), add(b, a);
    43. }
    44. dfs(1);
    45. printf("%d\n", ans);
    46. return 0;
    47. }

    二、847 图中点的层次

    活动 - AcWing

    给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环。

    所有边的长度都是 1,点的编号为 1∼n。

    请你求出 1 号点到 n 号点的最短距离,如果从 1 号点无法走到 n 号点,输出 −1。

    输入格式

    第一行包含两个整数 n 和 m。

    接下来 m 行,每行包含两个整数 a 和 b,表示存在一条从 a 走到 b 的长度为 1 的边。

    输出格式

    输出一个整数,表示 1 号点到 n 号点的最短距离。

    数据范围

    1≤n,m≤105

    输入样例:

    1. 4 5
    2. 1 2
    3. 2 3
    4. 3 4
    5. 1 3
    6. 1 4

    输出样例:

    1
    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. const int N=1e5+10;
    6. int n,m;
    7. int q[N],d[N];
    8. int h[N],e[N],ne[N],idx;
    9. void add(int a,int b)
    10. {
    11. e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    12. }
    13. int bfs()
    14. {
    15. memset(d,-1,sizeof d);
    16. int hh=0,tt=0;
    17. d[1]=0;
    18. q[++tt]=1;
    19. while(hh<=tt)
    20. {
    21. auto t=q[hh++];
    22. for(int i=h[t];i!=-1;i=ne[i])
    23. {
    24. int j=e[i];
    25. if(d[j]==-1)
    26. {
    27. d[j]=d[t]+1;
    28. q[++tt]=j;
    29. }
    30. }
    31. }
    32. return d[n];
    33. }
    34. int main()
    35. {
    36. cin>>n>>m;
    37. memset(h, -1, sizeof h);
    38. for(int i=0;i
    39. {
    40. int a,b;
    41. cin>>a>>b;
    42. add(a,b);
    43. }
    44. cout<<bfs()<
    45. return 0;
    46. }

  • 相关阅读:
    Java多线程超级详解(只看这篇就够了)
    如何做好自动化测试?揭开测试项目团队的自动化实践过程……
    MATLAB 用语句新建和打开 Simulink 模型
    目标检测开源框架YOLOv6全面升级,更快更准的2.0版本来啦
    VUE3版本新特性
    使用NNO区域进行色偏检测
    [前端必学]精准控制webpack处理文件名hash的问题
    常用工具类之Spring-boot-configuration-processor的学习使用
    数据结构-链表(java)
    俄罗斯方块
  • 原文地址:https://blog.csdn.net/weixin_61639349/article/details/126021866