上后谈爱情

导航

 

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

输入格式:

输入说明:输入数据的第1行给出4个正整数NN、MM、SS、DD,其中NN(2\le N\le 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("没有最短路径\n");
              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 }

同时结果的显示:

posted on 2016-05-13 09:29  上后谈爱情  阅读(189)  评论(0编辑  收藏  举报