2022-6-21 真题练习-图-BFS
校招时部分企业笔试将禁止编程题跳出页面,为提前适应,练习时请使用在线自测,而非本地IDE。
描述
给出一张有向图 G(V,E) ,所有的边都是有向边,对于图上的一个点 v ,从 v 出发可以到达的点的集合记为 Sv ,特别地, v ∈ Sv,再定义一个点的集合 Tv:从Tv中的任意一个点出发,可以到达点 v ,特别地,v∈Tv简而言之,Sv是 v 能到的点的集合,而 Tv 是能到 v 的点的集合。
对于一个点 v ,如果 Tv中的点数严格大于 Sv 中的点数,那么 v 就是一个重要节点,输入一张图,输出图中重要节点的个数
数据范围: 1 \le n,m \le 1000 \1≤n,m≤1000 , 1 \le u,v \le n \1≤u,v≤n
输入描述:
第一行输入两个数 n,m ,分别表示点数和边数。 接下来 m 行,每行两个数 u , v 。表示一条从 u 到 v 的有向边,输入中可能存在重边和自环。
输出描述:
输出一个数,重要节点的个数
1 import java.util.*; 2 public class Main{ 3 static boolean[][] arrive; 4 static List<List<Integer>> graph; 5 public static void main(String[] args) { 6 Scanner sc = new Scanner(System.in); 7 int n = sc.nextInt(); 8 int m = sc.nextInt(); 9 graph=new ArrayList<>(); 10 for (int i=0;i<n+1;i++){ 11 graph.add(new ArrayList<>()); 12 } 13 for (int i=0;i<m;i++){ 14 int u=sc.nextInt(); 15 int v=sc.nextInt(); 16 graph.get(u).add(v); 17 } 18 arrive=new boolean[n+1][n+1]; 19 for (int i=1;i<=n;i++) bfs(i); 20 int[] t=new int[n+1]; 21 int[] s=new int[n+1]; 22 for (int i=1;i<=n;i++){ 23 for (int j=1;j<=n;j++){ 24 if (arrive[i][j]){ 25 t[j]++; 26 s[i]++; 27 } 28 } 29 } 30 int ans=0; 31 for (int i=1;i<=n;i++){ 32 if (t[i]>s[i]) ans++; 33 } 34 35 System.out.println(ans); 36 } 37 38 public static void bfs(int node){ 39 Queue<Integer> queue=new LinkedList<>(); 40 queue.offer(node); 41 arrive[node][node]=true; 42 while (!queue.isEmpty()){ 43 int cur=queue.poll(); 44 for (int x:graph.get(cur)){ 45 if (!arrive[node][x]){ 46 arrive[node][x]=true; 47 queue.offer(x); 48 } 49 } 50 } 51 } 52 }
思路:建图之后,遍历所有节点,并利用BFS找到所有能达到的节点。最后统计并判断。