坐地铁,求最短路径

博客围绕城市地铁环线问题展开,乘客小明要从始发站S到终点站T,只能换乘地铁环线。给出了输入格式,包括地铁环线数量、各环线站点数量及编号等。还提供了Java代码,通过递归方法计算小明最少乘坐的地铁数量,若无法到达则返回 -1。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

* 某个城市规划了多条地铁环线,每条线路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;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值