给出一张有向图 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);
}
}