• 07-图6 旅游规划(25 分)


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

    输入格式:

    输入说明:输入数据的第1行给出4个正整数N、M、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
    

    我的答案
      1 #include <stdio.h>
      2 #include <unistd.h>
      3 #include <stdlib.h>
      4 
      5 #define ERROR -1
      6 #define false 0
      7 #define true  1
      8 #define MaxVertexNum 100
      9 #define INFINITY     65535
     10 typedef int Vertex;
     11 typedef int WeightType;
     12 typedef char DataType;
     13 typedef int bool;
     14 
     15 
     16 typedef struct ENode *PtrToENode;
     17 struct ENode {
     18     Vertex V1, V2;
     19     WeightType Weight;
     20     WeightType Cost;
     21 };
     22 typedef PtrToENode Edge;
     23 
     24 typedef struct GNode *PtrToGNode;
     25 struct GNode {
     26     int Nv;
     27     int Ne;
     28     WeightType G[MaxVertexNum][MaxVertexNum];
     29     WeightType C[MaxVertexNum][MaxVertexNum];
     30 };
     31 typedef PtrToGNode MGraph;
     32 
     33 MGraph CreateGraph(int VertexNum);
     34 void InsertEdge(MGraph Graph, Edge E);
     35 MGraph BuildGraph(int Nv, int Ne);
     36 void PrintGraph(MGraph Graph);
     37 Vertex FindMinDist(MGraph Graph, int dist[], int collected[]);
     38 bool Dijkstra(MGraph Graph, int dist[], int path[], int cost[], Vertex S);
     39 void PrintDist(MGraph Graph, int dist[]);
     40 void PrintPath(int path[], int N);
     41 
     42 MGraph CreateGraph(int VertexNum)
     43 {
     44     Vertex V, W;
     45     MGraph Graph;
     46 
     47     Graph = (MGraph)malloc(sizeof(struct GNode));
     48     Graph->Nv = VertexNum;
     49     Graph->Ne = 0;
     50 
     51     for(V=0;V<Graph->Nv;V++)
     52         for(W=0;W<Graph->Nv;W++) {
     53             Graph->G[V][W] = INFINITY;
     54             Graph->C[V][W] = INFINITY;
     55         }
     56 
     57     return Graph;
     58 }
     59 
     60 void InsertEdge(MGraph Graph, Edge E)
     61 {
     62     Graph->G[E->V1][E->V2] = E->Weight;
     63     Graph->G[E->V2][E->V1] = E->Weight;
     64     Graph->C[E->V1][E->V2] = E->Cost;
     65     Graph->C[E->V2][E->V1] = E->Cost;
     66 }
     67 
     68 MGraph BuildGraph(int Nv, int Ne)
     69 {
     70     MGraph Graph;
     71     Edge E;
     72     int i;
     73 
     74     // scanf("%d", &Nv);
     75     Graph = CreateGraph(Nv);
     76 
     77     Graph->Ne = Ne;
     78     // scanf("%d", &(Graph->Ne));
     79     if(Graph->Ne != 0) {
     80         E = (Edge)malloc(sizeof(struct ENode));
     81         for(i=0;i<Graph->Ne;i++) {
     82             scanf("%d %d %d %d
    ", &E->V1, &E->V2, &E->Weight, &E->Cost);
     83             InsertEdge(Graph, E);
     84         }
     85     }
     86 
     87     return Graph;
     88 }
     89 
     90 void PrintGraph(MGraph Graph)
     91 {
     92     Vertex V, W;
     93     printf("Graph:
    ");
     94     for(V=0;V<Graph->Nv;V++) {
     95         for(W=0;W<Graph->Nv;W++) 
     96             printf("[%5d %5d]	" , Graph->G[V][W], Graph->C[V][W]);
     97         printf("
    ");
     98     }
     99     printf("-----------------------
    ");
    100 }
    101 
    102 Vertex FindMinDist(MGraph Graph, int dist[], int collected[])
    103 {
    104     Vertex MinV, V;
    105     int MinDist = INFINITY;
    106 
    107     for(V=0;V<Graph->Nv;V++) {
    108         if(collected[V] == false && dist[V]<MinDist) {      //未被访问并且距离最小
    109             MinDist = dist[V];
    110             MinV = V;
    111         }
    112     }
    113     if(MinDist < INFINITY)
    114         return MinV;
    115     else return ERROR;
    116 }
    117 
    118 bool Dijkstra(MGraph Graph, int dist[], int path[], int cost[], Vertex S)
    119 {
    120     int collected[MaxVertexNum];
    121     Vertex V, W;
    122 
    123     /* 初始化:此处默认邻接矩阵中不存在的边用INFINITY表示 */
    124     for(V=0;V<Graph->Nv;V++) {
    125         dist[V] = Graph->G[S][V];
    126         cost[V] = Graph->C[S][V];
    127         if(dist[V]<INFINITY)
    128             path[V] = S;
    129         else
    130             path[V] = -1;
    131         collected[V] = false;
    132     }
    133 // PrintPath(path, Graph->Nv);
    134     /* 先将起点收入集合 */
    135     dist[S] = 0;
    136     collected[S] = true;
    137 
    138     while(1) {
    139         /* V = 未被收录顶点中dist最小者 */
    140         V = FindMinDist(Graph, dist, collected);
    141 // printf("[FindMinDist] V:%d
    ", V);
    142         if(V == ERROR)      /* 若这样的V不存在 */
    143             break;          /* 算法结束 */
    144         collected[V] = true;    /* 收录 */
    145         for(W=0;W<Graph->Nv;W++) {      /* 对图中的每个顶点W */
    146             /* 若W是V的邻接点并且未被收录 */
    147             if(collected[W]==false && Graph->G[V][W]<INFINITY) {
    148                 if(Graph->G[V][W]<0)    /* 若有负边 */
    149                     return false;       /* 不能正确解决,返回错误标记 */
    150                 /* 若收录V使得dist[W]变小(两点距离比一点距离短) */
    151                 if(dist[V]+Graph->G[V][W]<dist[W]) {
    152                     dist[W] = dist[V] + Graph->G[V][W];     /* 更新dist[W] */
    153 // printf("[FindMinDist] dist[W(%d)]=%d
    ", W, dist[W]);
    154                     path[W] = V;        /* 更新S到W的路径 */
    155                     cost[W] = cost[V] + Graph->C[V][W];
    156                 } else if((dist[V]+Graph->G[V][W] == dist[W]) 
    157                             && (cost[V] + Graph->C[V][W] < cost[W])) {
    158                     cost[W] = cost[V] + Graph->C[V][W];
    159                 }
    160             }
    161         }
    162     }
    163 
    164     return true;    /* 算法执行完毕,返回正确标记 */
    165 }
    166 
    167 void PrintDist(MGraph Graph, int dist[])
    168 {
    169     Vertex V;
    170     for(V=0;V<Graph->Nv;V++) {
    171         printf("%d ", dist[V]);
    172     }
    173     printf("
    ");
    174 }
    175 
    176 void PrintPath(int path[], int N)
    177 {
    178     int i;
    179     printf("[Path] ");
    180     for(i=0;i<N;i++)
    181         printf("%d ",path[i]);
    182     printf("
    ");
    183 }
    184 
    185 int main()
    186 {
    187     int N, M;
    188     Vertex S, D;
    189     int *dist, *path, *cost;
    190     MGraph Graph;
    191     scanf("%d %d %d %d
    ", &N, &M, &S, &D);
    192     dist = (int *)malloc(sizeof(int)*N);
    193     path = (int *)malloc(sizeof(int)*N);
    194     cost = (int *)malloc(sizeof(int)*N);
    195     Graph = BuildGraph(N, M);
    196     // PrintGraph(Graph);
    197     Dijkstra(Graph, dist, path, cost, S);
    198     // PrintPath(path, N);
    199     printf("%d %d
    ", dist[D], cost[D]);
    200     return 0;
    201 }
    无欲速,无见小利。欲速,则不达;见小利,则大事不成。
  • 相关阅读:
    爬虫案例
    伪静态
    HTTP0.9、HTTP1.0、HTTP1.1、HTTP2的区别
    正向代理和反向代理
    数据结构继承
    APP 爬虫
    算法基础
    matplotlib
    Java类加载机制及自定义加载器
    SpringBoot war包部署到Tomcat服务器
  • 原文地址:https://www.cnblogs.com/ch122633/p/9001396.html
Copyright © 2020-2023  润新知