bfs输出路径 && 最短路(迪杰斯特拉)输出路径

问题描述

 

 

解决方法

1、像第一个问题那就是最短路问题(我代码采用迪杰斯特拉算法)实现

 

2、换乘次数最少,那就用bfs广搜来寻找答案。但是我的代码不能保证这个最少换乘是最短路程

 

 

代码

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<string.h>
  5 #include<queue>
  6 #include<vector>
  7 using namespace std;
  8 const int maxn=1e3;
  9 const int INF=0x3f3f3f3f;
 10 int on[maxn],v[maxn];
 11 //on数组是用来记录路径的
 12 //v数组是用来记录最短路径长度的
 13 struct shudui
 14 {
 15     int x,step;
 16 };
 17 struct shudui2
 18 {
 19     int x,value;
 20 };
 21 struct shudui1
 22 {
 23     int start,value;
 24     bool operator < (const shudui1 q)const  //这个是用于优先队列,最短路算法采用”迪杰斯特拉+堆优化“
 25     {
 26         return value<q.value;
 27     }
 28 };
 29 vector<shudui2>w[maxn];  //定义一个shudui2类型的vector容器
 30 void bfs(int st,int en)  //这个是用bfs找到最少换乘次数
 31 {
 32     //st代表起点,en代表终点
 33     int ans=INF;
 34     shudui str1,str2;
 35     system("cls");
 36     int flag=0;
 37     memset(on,0,sizeof(on));
 38     queue<shudui>r;
 39     //为bfs搜索创建一个队列
 40     str1.x=st;
 41     str1.step=0;
 42     r.push(str1);
 43     while(!r.empty())
 44     {
 45         str1=r.front();//从队列头取元素
 46         r.pop();
 47         int x=str1.x;
 48         for(int i=0; i<w[x].size(); ++i)  //遍历x这个点能到达的所有点,把它们都加入到队列中
 49         {
 50             str2.x=w[x][i].x;
 51             on[str2.x]=str1.x;  //记录路径
 52             if(w[x][i].x==en)  //这就代表找到了最短路径
 53             {
 54                 int index=en;
 55                 flag=1;
 56                 printf("最短换乘%d次\n",str1.step);
 57                 printf("以下是路径\n");
 58                 printf("%d",index);
 59                 while(on[index]>0)  //循环打印路径
 60                 {
 61                     index=on[index];
 62                     printf("--->%d",index);
 63                     if(index==st) break;
 64                 }
 65                 printf("\n");
 66                 break;
 67             }
 68 
 69             str2.step=str1.step+1;  //每换乘一次要加1
 70             r.push(str2);
 71         }
 72         if(flag) break;
 73     }
 74     while(!r.empty()) r.pop();
 75     if(!flag)
 76     {
 77         printf("没有通向此处航线\n");
 78     }
 79 }
 80 void JK(int s,int e)  //迪杰斯特拉算法求最短路
 81 {
 82     //s是起点,e是终点
 83     system("cls");
 84     memset(on,0,sizeof(on));
 85     memset(v,INF,sizeof(v));
 86     priority_queue<shudui1>r;
 87     shudui2 str2;
 88     shudui1 str1;
 89     v[s]=0;
 90     str1.start=s;
 91     str1.value=0;
 92     r.push(str1);  //把起点放入优先队列
 93     while(!r.empty())
 94     {
 95         int x,y;
 96         str1=r.top();  //从优先队列头拿出元素
 97         r.pop();
 98         x=str1.start;
 99         y=str1.value;
100         if(v[x]<y) continue;
101         //说明在这个点再此之后又入队了
102         //此次出队的并不是s到这个点的最短路,
103         //所以在这次更新前点v所连的点已经更过一次了
104         //所以后面也不会进行松弛操作
105         int len=w[x].size();
106         for(int i=0; i<len; ++i) //
107         {
108             str2=w[x][i];
109             if((v[x]+str2.value<v[str2.x])) //遍历x这个点能到达的所有点,把它们都加入到队列中
110             {
111                 on[str2.x]=x;  //记录路径
112                 v[str2.x]=v[x]+str2.value;
113                 str1.start=str2.x;
114                 str1.value=v[str2.x];
115                 r.push(str1);
116             }
117         }
118     }
119     printf("最短路径长度为%d\n",v[e]);
120     printf("路径如下\n");
121     printf("%d",e);
122     int x=e;
123     while(on[x]>0)  //循环打印路径
124     {
125         x=on[x];
126         printf("-->%d",x);
127     }
128     printf("\n");
129 }
130 int main()
131 {
132     int n,m,x;
133     printf("输入有几个点,有几条边\n");
134     scanf("%d%d",&n,&m);
135     printf("依次输入每条路线的起点、终点、距离\n");
136     while(m--)
137     {
138         shudui2 str2;
139         int x,y,z;
140         scanf("%d%d%d",&x,&y,&z);
141         str2.x=y;
142         str2.value=z;
143         w[x].push_back(str2);  //往vector容器里面添加元素
144         str2.x=x;
145         w[y].push_back(str2);
146     }
147     while(1)
148     {
149         int s,e;
150         system("cls");
151         printf ( "                                                                 \n");
152         printf ( "                                                                 \n");
153         printf ( "                                                                 \n");
154         printf ("--------------------------------------                           \n");
155         printf ("--------------------------------------\n");
156         printf ("--------丨[0]最短路程            丨---\n");
157         printf ("--------丨[1]最少换乘            丨---\n");
158         printf ("--------丨[2]结束                丨---\n");
159         printf ("----------输入相应数字----------------\n");
160         printf ("---------------------------------------                           \n");
161         printf ( "                                                                 \n");
162         printf ( "                                                                 \n");
163         scanf("%d",&x);  //正常if判断语句
164         if(x==0)
165         {
166             printf("输入终点编号、起点编号\n");
167             scanf("%d%d",&s,&e);
168             JK(s,e);
169         }
170         else if(x==1)
171         {
172             printf("输入终点编号、起点编号\n");
173             scanf("%d%d",&s,&e);
174             bfs(s,e);
175         }
176         else if(x==2)
177         {
178             break;
179         }
180         else printf("输入格式不正确\n");
181         system("pause");
182     }
183     return 0;
184 }
185 /*
186 测试数据
187 5 5
188 1 2 20
189 2 3 30
190 3 4 20
191 4 5 20
192 1 5 100
193 */
posted @ 2020-01-02 19:10  kongbursi  阅读(695)  评论(0编辑  收藏  举报