题解 | #相遇#

相遇

https://www.nowcoder.com/practice/5dc1ccabaa0442d8b83f00ec74b225fa

import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int t = scanner.nextInt();
        List<List<Integer>> e = new ArrayList<>();        // 邻接表
        int[] ind = new int[n];        // 入度
        int[] tuo = new int[n];        // 拓扑排序数组
        int[] nituo = new int[n];      // 根据拓扑下标获得节点
        // 创建邻接表
        for (int i = 0; i < n; i++) e.add(new ArrayList<>());        // 每个节点均可拥有许多相邻节点
        for (int i = 0; i < m; i++) {
            int u = scanner.nextInt()-1;
            int v = scanner.nextInt()-1;
            e.get(u).add(v);
            ind[v]++;
        }
        // 拓扑排序
        Queue<Integer> q = new LinkedList<>();
        for (int i = 0; i < n; i++) if (ind[i] == 0) q.add(i);
        int count = 0;
        while (!q.isEmpty()) {
            int u = q.poll();
            tuo[u] = ++count;
            nituo[count-1] = u;
            for (int i : e.get(u)) if (--ind[i] == 0) q.add(i);
        }
        // System.out.println(Arrays.toString(tuo));
        // System.out.println(Arrays.toString(nituo));
        // 动态规划
        int[] dp = new int[n];
        dp[t-1] = 1;
        // 从后向前 相当于是叶子节点向上
        for (int i = n - 1; i >= 0; i--) {
            int v = nituo[i];
            for (int next : e.get(v)) dp[v] = (dp[v] + dp[next])%100007;        // 某点到达终点方案数量即为与之相邻节点到达终点所有方案数量之和
        }
        int query = scanner.nextInt();
        for (int i = 0; i < query; i++) {
            int start = scanner.nextInt();
            System.out.println(dp[start-1]);
        }
    }
}

基本可以说是直接CV大佬的代码了

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务