dijkstra拓展(规划最短航线问题)

本文介绍了如何使用Dijkstra算法来规划最短航线问题,详细阐述了题目的描述、输入输出要求,并提供了已通过验证的代码实现。

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

1、牛客网原题:

题目描述

“呼!!终于到了,可是接下来要怎么走才能到达楚楚街港港呢?”亮亮在醋溜港直发愁。 突然“啾”的一下,一只银色小船出现在亮亮的面前,上面坐着小精灵丹丹“又见面了,有什么可以帮助你的么?”小精灵向亮亮眨了眨眼睛,微笑着说。 “我想去楚楚街港,但我不知道要怎么走,请问你可以告诉我么?”亮亮按捺着激动的心情轻声问道。 “楚楚街港呀......那是个特别美好的地方”小精灵歪着头想了想,说“我只能告诉你大海上所有的航线,剩下的就只能靠你自己啦~” “只有所有的航线呀”,亮亮的内心再三挣扎,却又没有其他的办法。 “不管有多困难,我一定要达到楚楚街港,请你告诉我吧”亮亮坚定地对小精灵说。 小精灵欣赏地点了点头,递给亮亮一张航线图,并叮嘱道“时限是1000天,一定要到哦~”,然后如来时一般“啾”的一声,消失了。 亮亮现在迫切地想要抵达楚楚街港,请问亮亮最快能在第几天抵达楚楚街港呢?

输入描述:

一行包含两个整数N(2<=N<=500),M(1<=M<=2000),用单个空格隔开。表示公有N个港,M条航线。起点为1,终点为N。
接下来M行,每行包含五个整数P,Q(1<=P,Q<=n), K(1<=K<=1000), X,Y(0<=X,Y<=10000),代表P,Q两个港有航线并需要K天,并且该航线在第X天到第Y天天气恶劣不可通行。

输出描述:

一个整数,即亮亮最快能在第几天抵达楚楚街港
示例1

输入

4 4
       
2 1 1 7 13

4 3 2 10 11

1 3 8 9 12

2 3 3 2 10

输出

14



2、code实现:已ac

package schooloffer;

import java.util.ArrayList;
import java.util.Scanner;

/**
 * Created by caoxiaohong on 17/10/23.
 * “呼!!终于到了,可是接下来要怎么走才能到达楚楚街港港呢?”亮亮在醋溜港直发愁。 突然“啾”的一下,一只银色小船出现在亮亮的面前,上面坐着小精灵丹丹“又见面了,有什么可以帮助你的么?....
 * 算法思想:dijkstra
 */
class Range{
    int P,Q,X,Y;
    Range(int p,int q,int x,int y){
        this.P=p;
        this.Q=q;
        this.X=x;
        this.Y=y;
    }
}
public class AirRoute {
    static int minLen=Integer.MAX_VALUE;//结果
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        while (scanner.hasNext()){
            //N个港,M条航线
            int N=scanner.nextInt();
            int M=scanner.nextInt();

            //每行包含五个整数P,Q(1<=P,Q<=n), K(1<=K<=1000), X,Y(0<=X,Y<=10000),代表P,Q两个港有航线并需要K天,并且该航线在第X天到第Y天天气恶劣不可通行。
            int[][] matrix=new int[N+1][N+1];
            for(int i=0;i<N+1;i++){
                for(int j=0;j<N+1;j++){
                    matrix[i][j]=Integer.MAX_VALUE;
                }
            }
            ArrayList<Range> ranges=new ArrayList<Range>();
            int p,q,k,x,y;
            for(int i=0;i<M;i++){
                p=scanner.nextInt();
                q=scanner.nextInt();
                k=scanner.nextInt();
                x=scanner.nextInt();
                y=scanner.nextInt();
                //if是因为阴天而比普通dijkstra多出来的内容
                if(p==1 || q==1){
                    k= ( (k>=x && k<=y) || (k>=y))?y+k:k;
                }
                matrix[p][q]=k;
                matrix[q][p]=k;

                //下面4行code也是因为阴天而多出来的内容
                Range tmp=new Range(p,q,x,y);
                ranges.add(tmp);
                tmp=new Range(q,p,x,y);
                ranges.add(tmp);

            }
            //调用算法
            dijkstra(matrix,ranges,1);
            System.out.println(matrix[1][N]+1);
        }
    }

    /**
     * 主算法
     * @param matrix 临接矩阵
     * @param ranges 阴雨天时间范围
     * @param start  起点
     */
    private static void dijkstra(int[][] matrix,ArrayList<Range> ranges,int start){
        int n=matrix.length;//0~(n-1):实际上只有n-1个点.
        boolean[] isVisited=new boolean[n];
        isVisited[start]=true;//初始化节点start

        int k;
        for(int i=1;i<=n-2;i++){//将n-1个节点添加进来
            k=-1;
            int minValue=Integer.MAX_VALUE;
            for(int j=1;j<n;j++){//查找从start到j最短的点
                if(j!=start && !isVisited[j] && matrix[start][j]<minValue){
                    k=j;
                    minValue=matrix[start][j];
                }
            }
            isVisited[k]=true;

            //添加了k节点后,修改其他未访问的各个节点的最短路径
            for(int j=1;j<n;j++){
                if(!isVisited[j] && matrix[k][j]!=Integer.MAX_VALUE){
                    //下面的code是和阴天有关系的操作,和普通dijkstra不同的地方
                    int min;
                    int fromDay=-1,toDay=-1;
                    for(int m=0;m<ranges.size();m++){
                        if(ranges.get(m).P==k  && ranges.get(m).Q==j){
                            fromDay=ranges.get(m).X;
                            toDay=ranges.get(m).Y;
                            break;
                        }
                    }
                    if(fromDay==-1)
                        continue;
                    if( (matrix[start][k]>=fromDay && matrix[start][k]<=toDay) || (matrix[start][k]+matrix[k][j]>=fromDay && matrix[start][k]<=fromDay)){
                        min=toDay+matrix[k][j];
                    }else{
                        min=matrix[start][k]+matrix[k][j];
                    }
                    if(min<matrix[start][j])
                        matrix[start][j]=min;
                }
            }
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值