• 拓扑排序求最长路


    P1807 最长路 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

    题目要求我们求出第1号到第n号节点之间最长的距离。

    我们想到使用拓扑排序来求最长路。

    正常来讲,我们应该把1号节点入队列,再出队列,把一号节点能到达的所有的点的入度减一,并且将这些点求到达一号节点的最大距离。如果一个节点的入度为0,那说明所有与他直接来链接的点都跑了一边,最后最大的也就跑出来了。即使任意两个点有多条链接路径也不碍事,为什么呢?举个例子,一号和二号点有三条路径分别为1,2,3,我们放进队列里后,会先后跑这三段长度最后取得最优。但是这道题目有个小坑点,那就是这种情况

    这种情况下我们初始时期是只存入了一号节点所置。

    由于3号节点还有一条入度,而2号节点我们没有初始化放入,即使他的入度为0也不能进入队列,所以3号节点无法到达,但实际1号节点可以到达3号节点,解决方法就是首先把非1号的所有的入度为0的节点先入队列,然后排除干扰,最后就可以按照原步骤进行了。

    附上代码

    1. import java.io.BufferedReader;
    2. import java.io.IOException;
    3. import java.io.InputStreamReader;
    4. import java.io.PrintWriter;
    5. import java.math.BigInteger;
    6. import java.math.MathContext;
    7. import java.security.PublicKey;
    8. import java.sql.SQLIntegrityConstraintViolationException;
    9. import java.util.ArrayList;
    10. import java.util.Arrays;
    11. import java.util.Collections;
    12. import java.util.Comparator;
    13. import java.util.Iterator;
    14. import java.util.LinkedList;
    15. import java.util.Objects;
    16. import java.util.PriorityQueue;
    17. import java.util.Scanner;
    18. import java.util.TreeMap;
    19. import java.util.TreeSet;
    20. public class Main {
    21. public static void main(String[] args) throws NumberFormatException, IOException {
    22. Scanner sc=new Scanner(System.in);
    23. BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    24. PrintWriter pw1=new PrintWriter(System.out);
    25. String[] aStrings=br.readLine().split(" ");
    26. aa=Integer.parseInt(aStrings[0]);
    27. bb=Integer.parseInt(aStrings[1]);
    28. al1=new ArrayList[aa+1];
    29. int a;
    30. rudu=new int[aa+1];
    31. for(a=1;a<=aa;a++) {
    32. al1[a]=new ArrayList<>();
    33. }
    34. for(a=1;a<=bb;a++) {
    35. String[] bStrings=br.readLine().split(" ");
    36. int b=Integer.parseInt(bStrings[0]);
    37. int c=Integer.parseInt(bStrings[1]);
    38. int d=Integer.parseInt(bStrings[2]);
    39. al1[b].add(new edge(c, d));//存储边
    40. rudu[c]++;//入度加一
    41. }
    42. for(a=2;a<=aa;a++) {
    43. if(rudu[a]==0) {//为了解决上述问题我们从2号节点开始,来求得所有入读为0的点的序号
    44. ll1.add(a);
    45. }
    46. }
    47. dis=new int[aa+1];
    48. Arrays.fill(dis, Integer.MIN_VALUE);
    49. dis[1]=0;//初始点到初始点的距离肯定为0
    50. ll1.add(1);//在这里最后加入初始点
    51. while(ll1.size()!=0) {//取出入读为0的点
    52. int a1=ll1.remove();
    53. for(edge b1:al1[a1]) {
    54. dis[b1.to]=Math.max(dis[b1.to], dis[a1]+b1.length);
    55. rudu[b1.to]--;//进行值得更改
    56. if(rudu[b1.to]==0) {//入度为0那么就加入队列
    57. ll1.add(b1.to);
    58. }
    59. }
    60. }
    61. if(dis[aa]==Integer.MIN_VALUE) {
    62. System.out.println("-1");
    63. }
    64. else {
    65. System.out.println(dis[aa]);
    66. }
    67. }
    68. public static int aa;//点的总数
    69. public static int bb;//边的总数
    70. public static ArrayList[] al1;//存储边的集合
    71. public static int[] rudu;//记录每一个点的入度
    72. public static LinkedList ll1=new LinkedList<>();//记录每一个入度为0的点
    73. public static int[] dis;//记录每个点距离初始点的距离。
    74. }
    75. class edge{
    76. int to;
    77. int length;
    78. public edge(int to, int length) {
    79. super();
    80. this.to = to;
    81. this.length = length;
    82. }
    83. }

  • 相关阅读:
    AUTOSAR配置工具开发教程 – 改造篇(方法创建)
    Pytorch+cpp_cuda extension 课程一
    C语言之数组练习题
    多臂老虎机
    vue中::v-deep的用法
    【iOS】单例模式
    教科书级别 IDEA中用Maven手工搭建Spring Boot项目
    ZooKeeper中,关于节点(znode)的一些概念
    lingo问题需要解决
    微信小程序4
  • 原文地址:https://blog.csdn.net/m0_73862548/article/details/133798020