给出一张有向图 G(V,E) ,所有的边都是有向边,对于图上的一个点 v ,从 v 出发可以到达的点的集合记为 Sv ,特别地, v ∈ Sv,再定义一个点的集合 Tv:从Tv中的任意一个点出发,可以到达点 v ,特别地,v∈Tv简而言之,Sv是 v 能到的点的集合,而 Tv 是能到 v 的点的集合。
对于一个点 v ,如果 Tv中的点数严格大于 Sv 中的点数,那么 v 就是一个重要节点,输入一张图,输出图中重要节点的个数
数据范围: ,
第一行输入两个数 n,m ,分别表示点数和边数。 接下来 m 行,每行两个数 u , v 。表示一条从 u 到 v 的有向边,输入中可能存在重边和自环。
输出一个数,重要节点的个数
4 3 2 1 3 1 1 4
2
样例解释:重要节点是1,4。
暴力
import java.util.*; public class Main { static int bfs(List<Set<Integer>> g, int n, int x) { LinkedList<Integer> q = new LinkedList<>(); boolean used[] = new boolean[n+1]; q.offer(x); int res = 1; while(!q.isEmpty()) { int cur = q.poll(); for(int item : g.get(cur)) { if(used[item] == false) { res ++; q.offer(item); used[item] = true; } } } return res; } public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(), m = sc.nextInt(); List<Set<Integer>> g = new ArrayList<>(); // a -> b List<Set<Integer>> g2 = new ArrayList<>(); // b -> a for(int i=0; i <= n; i++) { g.add(new HashSet<>()); g2.add(new HashSet<>()); } for(int i=0; i < m; i++) { int a = sc.nextInt(), b = sc.nextInt(); if(a != b) { g.get(a).add(b); g2.get(b).add(a); } } int res = 0; for(int i=1; i <= n; i++) { int s = bfs(g, n, i); int t = bfs(g2, n, i); if(s < t) res++; } System.out.println(res); } }