题目详情

考察点:图、拓扑序列。
给定一个有向无环图和它的一系列点序列,输出属于其拓扑序列的点序列索引。

我的版本

暴力求解,即对于当前序列的当前判断点A,判断有无未取出的点指向当前点A,时间复杂度为2021/12/03 PAT1146 Topological Order - 钟珊珊 - 图1,有个实例不能AC。实现过程中踩的坑主要是nextInt读取数据,如果判断不符条件,注意要将当前行的数据全部读取出来。这道题用BufferedReader可能更合适。此外,这道题在记录边的时候取巧了,将点的值作为点的索引,使用int矩阵存储边。

  1. import java.util.*;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner sc = new Scanner(System.in);
  5. int n = sc.nextInt() + 1; // 顶点数
  6. int m = sc.nextInt(); // 边数
  7. int[][] eg = new int[n][n];
  8. for (int i = 0; i < m; i ++) {
  9. int x = sc.nextInt();
  10. int y = sc.nextInt();
  11. eg[x][y] = 1; // x -> y
  12. }
  13. sc.nextLine(); // nextInt与nextLine切换时需要注意一点【nextInt读取数之后将光标放在同一行;nextLine读取到\n,并将光标放到下一行】
  14. int k = Integer.parseInt(sc.nextLine()); // 序列数
  15. String rs = "";
  16. for (int i = 0; i < k; i ++) {
  17. int[] b = new int[n]; // 记录对应点是否已取出
  18. int t = 1;
  19. String[] line = sc.nextLine().split(" ");
  20. for (t = 0; t < n-1; t ++) {
  21. int x = Integer.parseInt(line[t]);
  22. for (int j = 1; j < n; j ++) {
  23. if (b[j] == 0 && eg[j][x] == 1) { // 点未排出且能指向当前排出的点
  24. t = n - 1;
  25. break;
  26. }
  27. }
  28. b[x] = 1;
  29. }
  30. if (t == n) {
  31. if (rs.length() == 0) {
  32. rs = "" + i;
  33. } else {
  34. rs += " " + i;
  35. }
  36. }
  37. }
  38. System.out.println(rs);
  39. }
  40. }

参考版本

PAT平台的代码效率评估可能不是很准确吧,C++同样的思路就可以全部AC……

#include <iostream>
#include <vector>
using namespace std;
int main() {
    int n, m, a, b, k, flag = 0, in[1010];
    vector<int> v[1010];
    scanf("%d %d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d %d", &a, &b);
        v[a].push_back(b);
        in[b]++;
    }
    scanf("%d", &k);
    for (int i = 0; i < k; i++) {
        int judge = 1;
        vector<int> tin(in, in+n+1);
        for (int j = 0; j < n; j++) {
            scanf("%d", &a);
            if (tin[a] != 0) judge = 0;
            for (int it : v[a]) tin[it]--;
        }
        if (judge == 1) continue;
        printf("%s%d", flag == 1 ? " ": "", i);
        flag = 1;
    }
    return 0;
}