树与图的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();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)