1.题目
给定一个n个点m条边的有向图,图中可能存在重边和自环。
所有边的长度都是1,点的编号为1~n。
请你求出1号点到n号点的最短距离,如果从1号点无法走到n号点,输出-1。
输入格式
第一行包含两个整数n和m。
接下来m行,每行包含两个整数a和b,表示存在一条从a走到b的长度为1的边。
输出格式
输出一个整数,表示1号点到n号点的最短距离。
数据范围
1≤n,m≤1051≤n,m≤105
输入样例:
4 5
1 2
2 3
3 4
1 3
1 4
输出样例:
1
2.分析
所有边的长度都是1,所以可以使用宽度搜索BFS。
- 通过队列实现bfs,从原点出发,往指向的点进行枚举,并且相继进栈
- 队列中元素出队列时,枚举下一层
- 数组d[]记录1到i最短距离时的值,若值为-1表示没有遍历过该点
注意:边权都是1才能使用bfs搜最短路
3.代码
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Code_0708_TreeBfs {
//图中点的层次
static int n;
static int N = 100010;
//h是代表头节点
static int[] h = new int[N];
//存储的值
static int[] e = new int[N];
//下一个的索引
static int[] ne = new int[N];
static int idx;
//只遍历一次
static int[] dist = new int[N];
//树和图都是这么做的!
//将b插到a的后面
static void add(int a , int b){
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
// 以u为根的子树中,点的数量
static int bfs(){
//初始化为- 1 代表没有访问过
for (int x : dist){
x = -1;
}
Queue<Integer> queue = new LinkedList();
queue.add(1);
dist[1] = 0;
while (!queue.isEmpty()){
int t = queue.poll();
for (int i = h[t]; i != -1;i = ne[i]){
int j = e[i];
if (dist[j] == -1){
dist[j] = dist[t] + 1;
queue.add(j);
}
}
}
return dist[n];
}
public static void main(String[] agrs){
//把里面的值都赋值成-1
//init
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
for (int x : h){
x = - 1;
}
for (int i = 0;i < n - 1;i++){
int a, b;
a = sc.nextInt();
b = sc.nextInt();
add(a,b);
}
System.out.println(bfs());
}
}