树与图的dfs与bfs遍历-java

题目所属分类

树与图的深度优先遍历与树与图的广度优先遍历

846. 树的重心(dfs)

在这里插入图片描述

输入样例
9
1 2
1 7
1 4
2 8
2 5
4 3
3 9
4 6
输出样例:
4

本题的本质是树的dfs, 每次dfs可以确定以u为重心的最大连通块的节点数,并且更新一下ans。
也就是说,dfs并不直接返回答案,而是在每次更新中迭代一次答案。
这样的套路会经常用到,在 树的dfs 题目中

题解

重心的讲解
在这里插入图片描述

在这里插入图片描述

(数组建立邻接表) 树的dfs
//邻接表
int h[N], e[N * 2], ne[N * 2], idx;

void add(int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
树的bfs模板
// 需要标记数组st[N],  遍历节点的每个相邻的便
void dfs(int u) {
    st[u] = true; // 标记一下,记录为已经被搜索过了,下面进行搜索过程
    for (int i = h[u]; i != -1; i = ne[i]) {
        int j = e[i];
        if (!st[j]) {
            dfs(j);
        }
    }
}
import java.util.Scanner;
class Main{
    private   static int N = 100010;
      private  static int M = 200020;
       static int n ; 
       static int [] h = new int [N];
       static  int [] e = new int [M];
        static int [] ne = new int [M];
       static boolean[] st = new boolean [M];
       static int  idx  =0;
         static int ans = N;
    public static void main(String [] args){
        Scanner scan = new Scanner(System.in);
          n = scan.nextInt();
        for(int i = 0 ; i < N ; i++){
            h[i] = -1 ;
        }
       for(int i = 0 ; i < n-1 ; i++){
            int a = scan.nextInt();
            int b = scan.nextInt();
            add(a,b);
            add(b,a);
        }
        dfs(1);
        System.out.println(ans);
    }
    public static void add (int a ,int b ){
        e[idx] = b ;
        ne[idx] = h[a];
        h[a] = idx++;
    }
    //以u为根的子树大小
    static int dfs(int u ){
        int res = 0 ; //每一个连通块大小的最大值
        int sum = 1 ;//当前子树的大小
        st[u] = true;
        for(int i = h[u] ; i!= -1 ; i =ne[i]){
            int j = e[i] ;
            if(!st[j]){
            int s   =  dfs(j);
               res = Math.max(res,s);
               sum += s;
            }
            
        }
        res = Math.max(res,n-sum);
        ans = Math.min(ans,res);
        return sum;
    }
}

847. 图中点的层次(bfs)

原题链接

在这里插入图片描述

输入样例:
4 5
1 2
2 3
3 4
1 3
1 4
输出样例:
1

题解

在这里插入图片描述

  d[1] = 0 ;
         Queue<Integer> q = new LinkedList<>();
         q.offer(1);
         while(!q.isEmpty()){
             int t = q.poll();
             for(int i = h[t] ; i != -1 ; i = ne[i]){
                 int j = e[i];
                 if(d[j] == -1 ){
                     d[j] = d[t] + 1 ;
                     q.offer(j);
                 }
             }
         }
        System.out.println(d[n]);

裸题模板

import java.util.Scanner;
public class Main{
    static int N = 100010,n,m,idx,hh,tt;
    static int[] h = new int[N],e = new int[N],ne = new int[N];
    static int[] d = new int[N],q = new int[N];
    //这个是单链表的模板
    public static void add(int a,int b){
        e[idx] = b;
        ne[idx] = h[a];
        h[a] = idx++;
    }
    public static int bfs(){
        hh = 0 ; tt = -1;
        d[1] = 0; // 第一个点是距离为0
        q[++tt] = 1; //然后将第一个点加进去
        //如果队列不是空的
        while(hh <= tt){
            int t = q[hh++]; //取出队头

            //然后遍历一下单链表
            for(int i = h[t] ; i != -1 ; i = ne[i]){

                int s = e[i]; //然后这个点用一个变量表示
                if(d[s] == -1){ //如果这个点是没走过的
                    d[s] = d[t] + 1; //然后将这个点距离加上1
                    q[++tt] = s;//然后将第二步的点加入到队尾中
                }
            }
        }
        return d[n]; //最后返回1到n的最短距离d


    }
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        n = scan.nextInt();
        m = scan.nextInt();
        //这里需要将距离跟头结点都赋值成-1
        for(int i = 1 ; i < N ; i++){
            h[i] = -1;
            d[i] = -1; 
        }
        for(int i = 0 ; i < m ; i ++ ){
            int a = scan.nextInt();
            int b = scan.nextInt();
            add(a,b);
        }
        System.out.println(bfs());
    }
}

 
import java.util.*;
public class Main{
    static int N = 100010,n,m,idx,hh,tt;
    static int[] h = new int[N],e = new int[N],ne = new int[N];
    static int[] d = new int[N],q = new int[N];
    //这个是单链表的模板
    public static void add(int a,int b){
        e[idx] = b;
        ne[idx] = h[a];
        h[a] = idx++;
    }
   static void bfs() {
        d[1] = 0;
       Queue<Integer> q = new LinkedList<Integer>();
        q.offer(1);
        while(!q.isEmpty()) {
            int head = q.poll();
            for(int i = h[head]; i != -1; i = ne[i] ) {//idx是边的索引,e[i]才是点的号码
                int j = e[i];
                if(d[j]==-1) {
                    d[j] = d[head]+1;
                    q.add(j);
                }
            }
        }
        System.out.println(d[n]);
    }

 
    
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        n = scan.nextInt();
        m = scan.nextInt();
        //这里需要将距离跟头结点都赋值成-1
        for(int i = 1 ; i < N ; i++){
            h[i] = -1;
            d[i] = -1; 
        }
        for(int i = 0 ; i < m ; i ++ ){
            int a = scan.nextInt();
            int b = scan.nextInt();
            add(a,b);
        }
        bfs();
    }
}

 
posted @   依嘫  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示