Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述:
给定一个 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的最短性,值得注意的是可能会存在重环和自环,所以我们要区别BFS和DFS,就是回溯时不需要恢复原来的情况。
三、AC 代码:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class acwing_847 {
/** N 个 点,M条边 */
public static int N,M;
/** 存放图 */
public static ArrayList<ArrayList<Integer>> th = new ArrayList<>();
/** 访问标识点 */
public static boolean[] visted = null;
/** 最短距离 */
public static int[] de = null;
/** 队列 */
public static Queue<Integer> queue = new LinkedList<>();
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
N = in.nextInt();
M = in.nextInt();
de = new int[ N + 1 ];
/** 初始化图和相关数组 */
for (int i = 0; i < N + 1; i++) {
th.add(new ArrayList<Integer>());
de[i] = -1;
}
for (int i = 0; i < M; i++) {
int a = in.nextInt();
int b = in.nextInt();
th.get(a).add(b);
}
visted = new boolean[ N + 1 ];
int sum = bfs();
System.out.println(sum);
}
public static int bfs(){
queue.add(1);
de[1] = 0;
visted[1] = true;
while (!queue.isEmpty()) {
Integer tmp = queue.remove();
Iterator node = th.get(tmp).iterator();
while (node.hasNext()) {
Integer num = (Integer) node.next();
if(!visted[num]){
queue.add(num);
de[num] = de[tmp] + 1;
visted[num] = true;
}
}
}
return de[N];
}
}
四、总结:
要分别BFS和DFS的区别,考虑好什么时候需要恢复原来的状态