• 旅游规划


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

    输入格式:

    输入说明:输入数据的第1行给出4个正整数NN、MM、SS、DD,其中NN(2le Nle 5002N500)是城市的个数,顺便假设城市的编号为0~(N-1N1);MM是高速公路的条数;SS是出发地的城市编号;DD是目的地的城市编号。随后的MM行中,每行给出一条高速公路的信息,分别是:城市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算法的应用,由于在题目中显示的是有两个权重的表示,首先必须要保证有最短的路径,在查看图中是否有多条具有相同最短路径,在其中选择最低的消费。

    本程序采用邻接链表的形式,当在有多条相同路径中,只在图中标记起始点的邻接边中的顶点。
      1 /*由于在这其中的过程中涉及到dijkstra,并且出现两条相等的路径的算法,如果*/
      2 /*在运算的过程中采用邻接链表的方式用dijkstra*/
      3 
      4 #include<iostream>
      5 #include<malloc.h>
      6 using namespace std;
      7 
      8 #define INF (100000)
      9 #define MAX 100
     10 //如果采用邻接链表的形式构造图,在每一个顶点中接下存储的边是其相邻的边
     11 typedef struct _Edge{
     12     int Adjv;
     13     int Weight;
     14     int costValue;
     15 
     16     _Edge *Next;
     17 }Edge,nedge;
     18 
     19 typedef struct _VNode
     20 {
     21     int  NodeName;
     22     bool flag;
     23     nedge *first_edge;
     24 }VNode;
     25 
     26 typedef struct _Graph{
     27     int Vernum;
     28     int Edgnum;
     29     VNode G[MAX];
     30 
     31 }MGraph;
     32 
     33 MGraph *Graph;
     34 
     35 void link_last(nedge *list, nedge *node)
     36 {  nedge *p=list;
     37 while(p->Next!=NULL)
     38 {
     39     p=p->Next;
     40 }
     41 p->Next=node;
     42 node->Next=NULL;
     43 }
     44 
     45 MGraph *BuildMyGraph(int N,int M)
     46 {     MGraph *pG;
     47     pG=(MGraph*)malloc(sizeof( _Graph));
     48 
     49     pG->Vernum=N;pG->Edgnum=M;
     50 
     51     //将点初始化
     52     for(int i=0;i<N;i++)
     53     {
     54         pG->G[i].NodeName=i;
     55         pG->G[i].flag=false;
     56         pG->G[i].first_edge=NULL;
     57     }
     58             //输入数据
     59       int c1,c2,w1,cost1,i,j;
     60     Edge *edge;
     61     for(i=0;i<pG->Edgnum;i++)
     62     {
     63         cin>>c1>>c2>>w1>>cost1;
     64         edge=(Edge*)malloc(sizeof(_Edge));
     65         edge->Adjv=c2;edge->Weight=w1;edge->costValue=cost1;edge->Next=NULL;
     66         for(j=0;j<pG->Vernum;j++)
     67         {
     68             if(c1==pG->G[j].NodeName)
     69             {
     70                 if(pG->G[j].first_edge==NULL)
     71                 {
     72                     pG->G[j].first_edge=edge;
     73                 }
     74                 else
     75                 {
     76                     link_last(pG->G[j].first_edge,edge);
     77                 }
     78             }
     79         }
     80     }
     81     return pG;
     82 }
     83 int get_weight(int b,int a)
     84 {
     85     Edge *egd=Graph->G[b].first_edge;
     86     int min=INF;
     87     if(b==a)
     88     {
     89         return 0;
     90     }
     91     while(egd!=NULL)
     92     {
     93         if(a==egd->Adjv)
     94         {
     95             if(egd->Weight<min)
     96             {
     97                 min=egd->Weight;
     98             }
     99         }
    100         egd=egd->Next;
    101     }
    102     return min;
    103 }
    104 
    105 int  Path(int prev[],int v,int e )
    106 {    int cost=0; Edge *item;
    107     //输出最短路径同时Graph标记号已经走过的点
    108     int i=0,j=0; int rev[MAX];
    109 
    110     for(i=e ;i!=v ; i=prev[i])
    111     {
    112             rev[j++]=i;
    113             if(prev[i]==v)
    114              Graph->G[i].flag=true;//只把与起始点相邻的定点进行标记
    115     }
    116     rev[j]=v;
    117     for(j;j>0;j--)
    118     {    int t=j-1;
    119         item=Graph->G[rev[j]].first_edge;
    120         {
    121             while(item!=NULL)
    122             {
    123                 if(rev[t]==item->Adjv)
    124                     {  cost=cost+item->costValue;
    125                          break;
    126                 }
    127                 item=item->Next;
    128             }
    129         }
    130     }
    131 
    132     return cost;
    133 }
    134 
    135 int dijkstra(int begin,int end,int *path)
    136 {//保证循环过程中begin和end所在点不能被标记
    137     int prev[MAX],dist[MAX],flag[MAX]; int path_cost;
    138 
    139     int i ,j ,k=begin;
    140 
    141     for(i=0;i<Graph->Vernum;i++)
    142     {
    143         flag[i]=0;
    144         prev[i]=-1;
    145         dist[i]=get_weight(begin ,i);
    146 
    147     }
    148 
    149     for(i=0;i<Graph->Vernum;i++)
    150     {
    151         if(dist[i]!=INF)
    152         {
    153             prev[i]=0;
    154         }
    155     }
    156 
    157 flag[begin]=1;
    158 dist[begin]=0;
    159 int min,tmp;
    160 //开始进行dijkstra计算
    161 for(i=1;i<Graph->Vernum;i++)
    162 {
    163     min=INF;
    164     for(j=0;j<(*Graph).Vernum;j++)
    165     {
    166         if(Graph->G[j].first_edge!=NULL)
    167         {
    168             if(dist[j]<min &&  !flag[j]  && Graph->G[j].flag==false)
    169             {
    170                 min=dist[j];
    171                 k=j;
    172             }
    173         }
    174     }
    175         flag[k]=1;
    176         //更新prev和dist矩阵
    177         for(j=0;j<Graph->Vernum;j++)
    178         {
    179             tmp=get_weight(k,j);
    180              tmp = (tmp==INF ? INF : (min + tmp));
    181              if(!flag[j] && (tmp<dist[j]) && Graph->G[j].flag==false)
    182              {
    183                  dist[j]=tmp;
    184                  prev[j]=k;
    185              }
    186         }
    187     }
    188 
    189     //dijkstra把起始点到各个顶点的最短路径,但是我们只需要从起始点到终点的路径就行了
    190             if(dist[end]!=INF)
    191             {
    192                 *path=dist[end];
    193               path_cost=    Path( prev,begin,end );
    194             }
    195        else
              {
                return -1;
                }
    196 return path_cost; 197 } 198 int main() 199 { 200 201 int N,M,W,D; 202 cin>>N>>M>>W>>D; 203 204 Graph=BuildMyGraph(N,M); 205 206 int cout=0; 207 for(int i=0;i<Graph->Vernum;i++) 208 { 209 if(W==Graph->G[i].NodeName) 210 { Edge *item=Graph->G[i].first_edge; 211 while(item!=NULL) 212 { 213 cout++; 214 item=item->Next; 215 } 216 } 217 } 218 219 int path_cost=0,temp=INF; 220 int path=0,temp_path=INF; 221 //接下来对图进行dijkstra算法研究 222 for(int j=0;j<cout;j++) 223 { 224 path_cost=dijkstra(W,D,&path); 225     if(path_cost==-1)
              {
                printf("没有最短路径 ");
                  exit(0);
                }
    226 Graph->G[D].flag=false; 227 if(temp_path>=path) 228 { 229 temp_path=path; 230 if(temp>=path_cost) 231 { 232 temp=path_cost; 233 } 234 } 235 else 236 { 237 printf("%d %d",D,temp); 238 return 0; 239 break; 240 } 241 242 } 243 return 0; 244 }

    同时结果的显示:

  • 相关阅读:
    【初学EXT】布局练习
    创建型模式总结(补充UML类图)
    数据库基本概念总结
    Word2010操作技巧总结
    VMWare虚拟机磁盘压缩和上网总结
    第一次用word2010发布文章到博客园记
    设计模式学习总结一原则及创建型模式
    为什么要开始写blog?
    Delphi异常处理总结
    设计模式总结之行为型模式
  • 原文地址:https://www.cnblogs.com/woainifanfan/p/5488251.html
Copyright © 2020-2023  润新知