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 */


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM