坐地铁,求最短路径

* 某个城市规划了多条地铁环线,每条线路routes[i]上都有一列地铁在上面循环行驶,并且每条环线的站点数量可以不同。
* 比如,现在存在一条线路routes[0] = [1, 4, 6, 7],表示第一列地铁会一直按照1->4->6->7->1->4->6->7->…的站台线路环绕行驶。
* 假设乘客小明刚开始不在任何一列地铁车厢内,他想从某一始发站S出发到达终点站T,中间只能换乘该城市规划的地铁环线,
* 求出小明最少乘坐的地铁数量。如果不能到达终点站,那么应该返回-1表示目的地不可达。
*
*
* 输入的第一行表示地铁环线数量N,取值范围[1, 500]
* 输入的第二行表示每条地铁环线站点数量的数组,取值范围[1, 10^5]
* 输入的第三行到第N+2行表示每条地铁环线的站点编号,取值范围[0, 10^6)
* 输入的倒数第二行表示始发站编号S
* 输入的最后一行表示终点站标号T
public class subway1701_地铁线 {

    public static int[][] subLine;

    public static boolean[][] useStat;

    public static boolean[] takeLineStatus;

    public static int min = -1;

    public static void main(String[] args) {
System.out.println(s.nextInt());

        Scanner s = new Scanner(System.in);
        int n = s.nextInt();

        useStat = new boolean[n][];
        subLine = new int[n][];
        takeLineStatus = new boolean[n];

        for (int i = 0; i < n; i++) {
            int c = s.nextInt();
            subLine[i] = new int[c];
            useStat[i] = new boolean[c];
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < subLine[i].length; j++) {
                subLine[i][j] = s.nextInt();
                useStat[i][j] = false;
            }
        }
        int start = s.nextInt();
        int end = s.nextInt();
        for (int i = 0; i < n; i++) {
            take(i, start, end, 0);
            takeLineStatus = new boolean[n];
        }
        System.out.println(min);
    }

    private static void take(int num, int start, int end, int takeTime) {
        if (min > 0 && takeTime > min) {
            return;
        }
        int[] subway = subLine[num];

        int started = -1;
        int ended = -1;
        for (int i = 0; i < subway.length; i++) {
            if (subway[i] == start) {
                started = i;
            }
            if (subway[i] == end) {
                ended = i;
            }
        }
        //经过起点与终端
        if (started >= 0 && ended >= 0) {
            if (start == end) {
                if (min < 0 || takeTime < min) {
                    min = takeTime;
                }
                return;
            }
            if (!takeLineStatus[num]) {
                takeTime++;
            }
            if (min < 0 || takeTime < min) {
                min = takeTime;
            }
            return;
        }
        //不经过起点
        if (started < 0) {
            return;
        }
        //已经过此站
        if (useStat[num][started]) {
            return;
        }
        boolean take = takeLineStatus[num];
        //多做一次
        if (!take) {
            takeTime++;
        }
        //经过
        useStat[num][started] = true;
        takeLineStatus[num] = true;
        for (int i = 0; i < subway.length; i++) {
            if (i == started) {
                continue;
            }
            //经过
            useStat[num][i] = true;
            for (int j = 0; j < subLine.length; j++) {
                if (j == num) {
                    continue;
                }
                take(j, subway[i], end, takeTime);
                takeLineStatus[num] = take;
            }
            useStat[num][i] = false;
        }
        useStat[num][started] = false;
    }

}

版权声明:本文为ZJUsunbin原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。