2022-6-19 真题练习
描述
一座城市有 n 个公交站台,站点从 1 到 n 编号,和 m 班公交车,公交车从 1 到 m 编号,乘坐每班公交车只需花费 1 元钱,第 i 班公交车一共经过 ti 个站点,分别为站点 ai,1,ai,2,...,ai,ti,小明可以乘坐第 i 班公交车从这 ti 个站台中的任意一个到达任意一个站点,如一班公交车经过站点 1,2,3,那么小明花费 1 元钱就可以从 1 到 2 ,从 1 到 3 ,从 2 到 1,从 3 到 1,从3 到 2。
小明想从 1 号站台到 n 号站台,问他最少花费多少钱。
数据范围: 2 \le n \le 10^5\2≤n≤105 , 1 \le m \le 10^5 \1≤m≤105 , 2 \le t_i \le n \2≤ti≤n , 2 \le n_i \times \sum_{i=1}^{m} t_i \le 10^5 \2≤ni×∑i=1mti≤105
输入描述:
第一行两个数 n , m。 接下来 m 行,依次描述公交车经过的站点,第 i 行开头一个数 t_i ,表示第 i 班公交车经过的站点数,接下来的 t_i 个数,依次表示这 t_i 个站点。
输出描述:
输出一个数,从 1 号站点到 n 号站点的最小代价,如果不能达到则输出 -1。
1 import java.util.*; 2 public class Main{ 3 public static void main(String[] args) { 4 Scanner sc = new Scanner(System.in); 5 int n = sc.nextInt(); 6 int m = sc.nextInt(); 7 List<List<Integer>> graph=new ArrayList<>(); 8 for (int i=0;i<m+n;i++) graph.add(new ArrayList<>()); 9 for (int i=0;i<m;i++){ 10 int t=sc.nextInt(); 11 for (int j=0;j<t;j++){ 12 int t_i=sc.nextInt(); 13 graph.get(n+i).add(t_i-1); 14 graph.get(t_i-1).add(n+i); 15 } 16 } 17 18 boolean[] visited=new boolean[m+n]; 19 visited[0]=true; 20 Queue<Integer> queue=new LinkedList<>(); 21 queue.offer(0); 22 int ans=-1,dis=1; 23 while (!queue.isEmpty()){ 24 int len=queue.size(); 25 for (int i=0;i<len;i++){ 26 int cur=queue.poll(); 27 if (cur==n-1&&ans==-1) ans=dis/2; 28 for (int node:graph.get(cur)){ 29 if (!visited[node]) { 30 queue.offer(node); 31 visited[node]=true; 32 } 33 } 34 } 35 dis++; 36 } 37 System.out.println(ans); 38 } 39 }
思路:把站点当成一个图的节点,把站点跟对应的站建立边。利用BFS遍历,出来的距离是原来的两倍。