邻接表
形如1一>3
这样的式子是推导式,说明结论1可以推导出结论了。
显然这样的推导式具有传递性:
如果1一>3
且3一>5
,那么肯定满足1一>5
。
现在给出n个推导式,你需要输出结论C能够推导出多少个不同的结论。
显然任何结论都可以推导出自己。
输入描述: 第一行输入两个整数n和c,含义如题意所述。 接下来n行,每行输入两个整数x,y,表示一个推导式x->y,可能会出现重复的推导式。 (1 <= n <= 10^5),(1 <= x,y,c <= 10000) 输出描述: 输出一个整数,表示结论c能推导出的不同结论的数目。
示例1: 输入: 5 1 1 2 1 3 3 9 4 2 8 1 输出: 4 说明: 根据推导式1一>2,1一>3,3一>9,可以判断出结论1可以推出结论2,3,9,加上本身总共4个结论。
|
代码实现
算法思路:
- 建立哈希表
edges
,记录每个数字所能推导的结论。
- 建立队列
que
,记录起始结论以及后续推导出的结论。
- 建立
HashSet
集合res
,记录最终答案。
- 建立哈希表,去除重复,以防循环推导。
import java.util.*;
public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int c = sc.nextInt(); HashMap<Integer, HashSet<Integer>> edges = new HashMap<>(); for(int i = 0; i < n; i++){ int a = sc.nextInt(), b = sc.nextInt(); if(!edges.containsKey(a)){ HashSet<Integer> set = new HashSet<>(); set.add(b); edges.put(a, set); }else{ if(!edges.get(a).contains(b)){ edges.get(a).add(b); } } } Queue<Integer> que = new ArrayDeque<>(); que.add(c); HashSet<Integer> res = new HashSet<>(); res.add(c); HashMap<Integer, Integer> map = new HashMap<>(); while(!que.isEmpty()){ int curr = que.peek(); que.poll(); map.put(curr, map.getOrDefault(curr, 0) + 1); if(map.get(curr) != 1)continue; if(!edges.containsKey(curr))continue; for(int i: edges.get(curr)){ res.add(i); que.add(i); } } System.out.println(res.size()); } }
|
参考
jiankychen教你学算法 - 学算法,看我就够了