zoukankan      html  css  js  c++  java
  • 07-图6 旅游规划

    题目:

      有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。

    输入格式:

    输入说明:输入数据的第1行给出4个正整数NM、S、D,其中N(2N500)是城市的个数,顺便假设城市的编号为0~(N1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。

    输出格式:

    在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。

    输入样例:

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

    输出样例:

    3 40

    要点:
      带有两个权值的路径,最短路径为首要权值,仍采用Dijkstra算法计算最短路径,但注意如果遇到最短路一样的情况下,最少花费要更新为少者
    代码:
    #include <iostream>
    #include <cstring>
    #define INFINITY 1000
    using namespace std;
    int G[550][550];
    int price[550][550];
    int collected[550];
    int dist[550];
    int cost[550];
    int N, M, S, D;
    
    void BuildGraph()
    {
        cin >> N >> M >> S >> D;
    
        for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++) {
            G[i][j] = INFINITY;
            price[i][j] = INFINITY;
        }
    
        for (int i = 0; i < M; i++) {
            int v, w, t, c;
            cin >> v >> w >> t >> c;
            G[v][w] = t;
            G[w][v] = t;
            price[v][w] = c;
            price[w][v] = c;
        }
    }
    
    void Dijkstra(int v0)
    {
        int i;
    
        for (i = 0; i < N; i++) {
            dist[i] = G[v0][i];
            cost[i] = price[v0][i];
        }
        collected[v0] = 1;
        dist[v0] = 0; cost[v0] = 0;
    
        for (i = 1; i < N; i++) {
            int v, w, Min = INFINITY;
            for (w = 0; w < N; w++) {
                if(!collected[w] && dist[w] < Min)
                {
                    Min = dist[w];
                    v = w;
                }
            }
            collected[v] = 1;
            for (w = 0; w < N; w++) {
                if (!collected[w]) {
                     if (G[v][w] + dist[v] < dist[w])
                    {
                        dist[w] = dist[v] + G[v][w];
                        cost[w] = cost[v] + price[v][w];
                    }
                    else if (dist[v] + G[v][w] == dist[w]
                            && cost[v] + price[v][w] < cost[w])
                        cost[w] = cost[v] + price[v][w];
                }
            }
        }
    
    }
    
    int main()
    {
        memset(collected, 0, sizeof(collected));
    
        BuildGraph();
        Dijkstra(S);
        cout << dist[D] << " " << cost[D];
    
        return 0;
    }

    其他类似问题:

    1.要求数最短路径有多少条

      count[s] = 1;

      如果找到最短路:count[w] = count[v]  v->w只有一条边 v的最短路径个数就是w个最短路径个数

      如果找到等长路:count[w] += count[v]  v->w只有一条边 s->v可能有很多最短路径 所以应该加上s->v的最短路径数

    2.要求边数最少的最短路

      相当于旅游规划问题的price权值都为1

      count[s] = 0

      如果找到更短路:count[w] = count[v] + 1

      如果找到等长路:count[w] = count[v] + 1

     
  • 相关阅读:
    IE6中overflow:hidden失效怎么办
    单例模式笔记
    linux 中的 "2>&1"含义
    linux 文件目录介绍
    centos 安装jdk
    SimpleDateFormat非线程安全
    Linux下Weblogic 11g R1安装和配置
    <meta>标签 的一些用法
    基于java的邮件群发软件
    史上最完整的集合类总结及hashMap遍历
  • 原文地址:https://www.cnblogs.com/whileskies/p/6862909.html
Copyright © 2011-2022 走看看