(Java)1030 Travel Plan

A traveler's map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/her starting city and the destination. If such a shortest path is not unique, you are supposed to output the one with the minimum cost, which is guaranteed to be unique.

旅行者地图显示了高速公路沿线城市之间的距离,以及每条高速公路的成本。现在你应该编写一个程序来帮助旅行者决定他/她的出发城市和目的地之间的最短路径。如果这样的最短路径不是唯一的,那么你应该输出成本最小的路径,它保证是唯一的。 

Input Specification:

Each input file contains one test case. Each case starts with a line containing 4 positive integers N, M, S, and D, where N (≤500) is the number of cities (and hence the cities are numbered from 0 to N−1); M is the number of highways; S and D are the starting and the destination cities, respectively. Then M lines follow, each provides the information of a highway, in the format:

每个输入文件包含一个测试用例。每种情况都以一行开始,该行包含4个正整数N、M、S和D,其中N(≤500)是城市的数量(因此城市的编号从0到N−1);M是公路的数量;S和D分别是出发城市和目的地城市。接下来是M条线,每条线提供高速公路的信息,格式如下: 

City1 City2 Distance Cost

where the numbers are all integers no more than 500, and are separated by a space.

其中,这些数字都是不超过500的整数,并用空格分隔。 

Output Specification:

For each test case, print in one line the cities along the shortest path from the starting point to the destination, followed by the total distance and the total cost of the path. The numbers must be separated by a space and there must be no extra space at the end of output.

对于每个测试用例,在一行中打印从起点到目的地的最短路径上的城市,然后是路径的总距离和总成本。数字必须用空格分隔,并且在输出的末尾不能有多余的空格。 

Sample Input:

4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20

Sample Output:

0 2 3 3 40
import java.util.ArrayList;
import java.util.Scanner;

class Main{
    static ArrayList<ArrayList<Integer>> v = new ArrayList<>();//邻接表
    static int n,m,s,d;
    static int [][]dis ;//存储矩阵,图,记录距离
    static int [][]cost;//记录花费
    static int []mindist;//记录起点到各个点的最短距离
    static ArrayList<Integer> path = new ArrayList<>();//记录路径
    static int mindist_toD = Integer.MAX_VALUE;//到终点的最短距离
    static int mincost_toD = Integer.MAX_VALUE;//到终点的最小花费
    static ArrayList<Integer> ans = new ArrayList<>();//记录最终的路径
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();
        s = sc.nextInt();
        d = sc.nextInt();
        dis = new int[n][n];
        cost = new int[n][n];
        mindist = new int[n];
        for(int i = 0 ; i < n ;i++)
        {
            //一定要先创建对象
            v.add(new ArrayList<>());
        }
        while(m -- > 0)
        {
            int i ,j , k , l;
            i = sc.nextInt();
            j = sc.nextInt();
            k = sc.nextInt();
            l = sc.nextInt();
            v.get(i).add(j);
            v.get(j).add(i);
            dis[i][j] = dis[j][i] = k;
            cost[i][j] = cost[j][i] = l;
        }
        for(int i = 0 ; i < n ;i++)
        {
            //初始化到各个点的最短距离
            mindist[i] = Integer.MAX_VALUE;
        }
        //深度优先
        dfs(s,0,0);
        for(int each : ans)
        {
            System.out.print(each + " ");
        }
        System.out.println(mindist_toD + " " + mincost_toD );
    }

    private static void dfs(int curcity , int curdis, int curcost) {//当前城市,当前走了多远,花费了多少
        if(curdis > mindist[curcity]) return ;//及时止损
        path.add(curcity);//加入路径
        if(curcity == d)//到达终点
        {
            if(curdis < mindist_toD || (curdis == mindist_toD && curcost < mincost_toD))//更新到达终点的最短距离
            {
                ans = new ArrayList<>(path);//这里一定要写new ,因为Java虽然没有指针,但是有引用类型,二者有异曲同工之处
                mindist_toD = curdis;//更新最短距离
                mincost_toD = curcost;
                mindist[d] = curdis;
            }
        }
        else
        {
            if(mindist[curcity] > curdis)
            {
                //更新起点到各个点的最短距离
                mindist[curcity] = curdis;
            }
            for(int each : v.get(curcity))
            {
                //对邻居再进行深度搜索
                dfs(each,curdis + dis[curcity][each],curcost + cost[curcity][each]);
            }
        }

        //回溯!!
        path.remove(path.size() - 1);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值