2020/10/28 bfs(广度优先遍历)

广度优先遍历-图中点的层次

题目

给定一个n个点m条边的有向图,图中可能存在重边和自环。
所有边的长度都是1,点的编号为1~n。
请你求出1号点到n号点的最短距离,如果从1号点无法走到n号点,输出-1。

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

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

数据范围
1≤n,m≤105

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

输出样例:
1

题目分析

广度优先遍历适用于寻找最短路径,因为我们是从出发点按照最短的距离找,所以一旦找到了就一定是最短路径.
同时,一定要清楚,所谓bfs(广度优先遍历),使用的是队列结构,而深度优先遍历则使用的是栈的结构. 基于这种数据结构,广度优先遍历只能要么模拟队列/要么直接使用队列,而深度优先遍历却能够直接使用递归函数.因为递归函数本质上就是调用栈来进行的.

算法解析

很简单,算法要做的就是
初始化队列:先给队列传入一个初始值
只要队列非空,就进行如下操作

  1. 弹出队头
  2. 把队头连接的子节点判断一下(当然判断的方式自己定),只要没被用过,就插入队尾.
    仅此而已

源代码

package test;

import java.util.*;
class Main{
 static int N=100010;
 //链表四件套
 static int index=0;
 static int[] h=new int[N];
 static int[] e=new int[N];
 static int[] ne=new int[N];
 //队列两件套
 static int[] q=new int[N];

 //本题专用 记录距离
 static int[] d=new int[N];
 public static void main(String[] args){
  Scanner sc=new Scanner(System.in);
  int n=sc.nextInt();
  int m=sc.nextInt();
  while(m-->0){
   int a=sc.nextInt();
   int b=sc.nextInt();
   add(a,b);
  }
  System.out.print(bfs(n));
 }
 public static void add(int a,int b){
  e[++index]=b;
  ne[index]=h[a];
  h[a]=index;
 }
 //队的初始化最好放在这里
 public static int bfs(int n){
  int hh=0;
  int tt=0;
  q[0]=1;

  Arrays.fill(d,-1);
  d[1]=0;
  while(hh<=tt){
   int x=q[hh++];
   for(int i=h[x];i!=0;i=ne[i]){
    int j=e[i];
    if(d[j]==-1){
     q[++tt]=j;
     d[j]=d[x]+1;
    }
   }
  }
  return d[n];
 }
 }

备注

这里我们使用Arrays.fill函数,让d[]数组全部填充-1,这样因为我们自己弄的一定都是>=0的,所以我们看到-1就知道我们没有操作过.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值