6)图[6]各顶点之间的最短路径

有向图图中任何两个可到达的顶点之间最短路径以及相应的长度

Dijkstra算法 和Floyd算法

 

  1 #include "iostream"
  2 #include "vector"
  3 #include "stdlib.h"
  4 using namespace std;
  5 
  6 const int MaxNumVertex  = 20; //最大顶点数
  7 const int infinity = 65535;//无穷大
  8 typedef int elementtype;       //elementtype 为int 型
  9 class graph{
 10 public:
 11     graph();
 12     ~graph();
 13     elementtype insertvertex(elementtype v); //在图中增加一个顶点
 14     elementtype insertedge(elementtype v,elementtype u,elementtype weight);//在图中增加一条从v顶点到u顶点的弧
 15     elementtype firstadj(elementtype v);//求图g中顶点v的第一个邻接点
 16     elementtype nextadj(elementtype v,elementtype m);//求图中顶点v的m邻接点之后的邻接点
 17     elementtype degreeout(elementtype v);//求图中顶点v的出度数
 18     elementtype FindDegreeout(elementtype oud[]);//各顶点的入度存放于出度数组中
 19     elementtype Dijkstra(elementtype v0);//求解从v0到各顶点的最短路径
 20     elementtype Floyd();//各顶点之间最短路径以及长度
 21     elementtype create();//创建图
 22     int  CurrentVertex;//当前顶点数
 23 
 24 private:
 25     elementtype vertex[MaxNumVertex];//顶点表
 26     elementtype edge[MaxNumVertex][MaxNumVertex];//图中弧的类型
 27     
 28 };
 29 
 30 /*
 31 *初始化
 32 */
 33 graph::graph()
 34 {
 35     CurrentVertex = 0; 
 36     int i,j;
 37     for (i=MaxNumVertex-1;i>=1;i--)
 38     {
 39         for (j=MaxNumVertex-1;j>=1;j--)
 40         {
 41             edge[i][j] = infinity;
 42 
 43         }
 44     }
 45     
 46 }
 47 
 48 /*
 49 *在图中增加一个顶点
 50 */
 51 elementtype graph::insertvertex(elementtype v)
 52 {
 53     //判断这个顶点是否已经存在
 54     int i;
 55     bool flags = true;
 56     for(i=1; i<=CurrentVertex; i++)
 57     {
 58         if(vertex[i]==v)
 59         {
 60             flags = false;
 61             break;
 62         }
 63     }
 64     
 65     if(flags)
 66     {
 67         CurrentVertex++;
 68         vertex[CurrentVertex] = v;
 69     }else{
 70         cout<<v<<"顶点已经存在!"<<endl;
 71     }
 72     return 0;
 73 }
 74 
 75 /*
 76 *在图中增加一条从v顶点到u顶点的弧
 77 */
 78 elementtype graph::insertedge(elementtype v,elementtype u,elementtype weight)
 79 {
 80     if(edge[v][u]!=infinity)
 81     {
 82         cout<<v<<"->"<<u<<"这条弧弧已经存在!"<<endl;
 83     }else{
 84         edge[v][u] = weight;
 85     }
 86     return 0;
 87 }
 88 
 89 
 90 /*
 91 *求图中顶点v的第一个邻接点
 92 */
 93 elementtype graph::firstadj(elementtype v)
 94 {
 95     int u,i;
 96     bool flags = true;//用于判断是否存在邻接点
 97     for(i=1;i<=CurrentVertex;i++)
 98     {
 99         if(edge[v][i]!=0){
100             u = i;
101             flags = false;
102             break;
103         }
104     }
105     if(flags) u = 0;//邻接点不存在
106     return u;
107 }
108 
109 /*
110 *求图中顶点v的m邻接点以后的邻接点
111 */
112 elementtype graph::nextadj(elementtype v,elementtype m)
113 {
114     int i,u;
115     bool flags = true;
116     for(i=m+1;i<=CurrentVertex;i++)
117     {
118         if(edge[v][i]!=0)
119         {
120             u = i;
121             flags = false;
122             break;
123         }
124     }
125     if(flags) u = 0;//邻接点不存在
126     return u;
127 }
128 /*
129 *求图中顶点v的出度数
130 */
131 elementtype graph::degreeout(elementtype v)
132 {
133     int i,num = 0;
134     for (i=1;i<=CurrentVertex;i++)
135     {
136         if(edge[v][i]!=infinity)num++;
137     }
138     return num;
139 }
140 
141 /*
142 *每个顶点的出度
143 */
144 elementtype graph::FindDegreeout(elementtype outd[])
145 {
146     int i;
147     for(i=1;i<=CurrentVertex;i++)
148     {
149         outd[i] = degreeout(i);
150     }
151     return 0;
152 }
153 
154 /*
155 *求解v0到各顶点的最短路径
156 */
157 elementtype graph::Dijkstra(elementtype v0)
158 {
159     int i,j,k,w,v;
160     bool solved[20];
161     int dist[20];
162     vector<vector<int>>path(MaxNumVertex);//存储v0到各顶点的路径
163     for(i=1;i<=CurrentVertex;i++)
164     {
165         solved[i] = false;
166     }
167 
168     solved[v0] = true;//将v0设置为已解顶点
169     for(i=1;i<=CurrentVertex;i++)
170     {
171         if(edge[v0][i]!=infinity)
172         {
173             dist[i] = edge[v0][i];
174             path[i].push_back(v0);
175             path[i].push_back(i);
176         }else{
177             dist[i] = infinity;
178         }
179     }
180 
181     for(i=1;i<CurrentVertex;i++)
182     {
183         int min = infinity;
184         for(j=1;j<=CurrentVertex;j++)//在未解顶点中搜索最近的顶点v
185         {
186             if((solved[j]==false)&&(dist[j]<min))
187             {
188                 min = dist[j];
189                 v = j;
190             }
191         }
192 
193         solved[v] = true;//所搜索到的当前最短的未解顶点为已解顶点
194         for(w=firstadj(v);w!=0;w=nextadj(v,w))//修改v的后继路径以及长度
195         {
196             if(dist[v]+edge[v][w]<dist[w])
197             {
198                 dist[w] = dist[v]+edge[v][w];//修改w的dist值
199                 path[w].clear();//清空w的path
200                 //重新形成w的path
201                 for(k=0;k<path[v].size();k++)
202                 {
203                     path[w].push_back(path[v][k]);
204                 }
205                 path[w].push_back(w);
206             }
207         }
208     }
209     for(i=1;i<=CurrentVertex;i++)
210     {
211         if((v0!=i)&&(dist[i]!=infinity))
212         {
213             cout<<"dist["<<v0<<"->"<<i<<"]:"<<dist[i]<<endl;
214             cout<<"path["<<v0<<"->"<<i<<"]:";
215             for(j=0;j<path[i].size();j++)
216             {
217                 if(j<path[i].size()-1)cout<<path[i][j]<<",";
218                 else cout<<path[i][j]<<endl;
219             }    
220         }
221     }
222     cout<<endl;
223     return 0;
224 }
225 
226 /*
227 *各顶点之间的最短路径以及长度
228 */
229 elementtype graph::Floyd()
230 {
231     int i,j,k,m;
232     vector<vector<vector<int>>> path(MaxNumVertex,vector<vector<int>>(MaxNumVertex));//存储两个顶点之间的额路径
233     for(i=1;i<=CurrentVertex;i++)//初始化路径矩阵path
234     {
235         for(j=1;j<=CurrentVertex;j++)
236         {
237             if(edge[i][j]!=infinity)
238             {
239                 path[i][j].push_back(i);
240                 path[i][j].push_back(j);
241             }
242         }
243     }
244 
245     for(k=1;k<=CurrentVertex;k++)//控制edge'k的求解
246     {
247         for(i=1;i<=CurrentVertex;i++)//求解edge'k[i][j]
248         {
249             for(j=1;j<=CurrentVertex;j++)
250             {
251                 if(i!=j)
252                 {
253                     if(edge[i][k]+edge[k][j]<edge[i][j])
254                     {
255                         edge[i][j] = edge[i][k]+edge[k][j];
256                         path[i][j].clear();
257                         for(m=0;m<path[i][k].size();m++)
258                         {
259                             path[i][j].push_back(path[i][k][m]);
260                         }
261                         for(m=1;m<path[k][j].size();m++)
262                         {
263                             path[i][j].push_back(path[k][j][m]);
264                         }
265                     }
266                 }
267             }
268         }
269     }
270     for(i=1;i<=CurrentVertex;i++)
271     {
272             
273             for(j=1;j<=CurrentVertex;j++)
274             {
275                 if((path[i][j].size()>0)&&(i!=j))
276                 {
277                     cout<<"dist["<<i<<"->"<<j<<"]:"<<edge[i][j]<<endl;
278                     cout<<"path["<<i<<"->"<<j<<"]:";
279                     for(k=0;k<path[i][j].size();k++)
280                     {
281                         if(k<path[i][j].size()-1)cout<<path[i][j][k]<<",";
282                         else cout<<path[i][j][k]<<endl;
283                     }
284                 }
285                 
286             }
287             cout<<endl;
288     }
289     return 0;
290 }
291 /*
292 *创建图
293 */
294 elementtype graph::create()
295 {
296     int i,numv,v,u,weight;
297     cout<<"please create graph"<<endl;
298     cout<<"input numvertex(顶点数):";
299     cin>>numv;
300     cout<<"input vertex(顶点):";
301     for(i=1;i<=numv;i++)
302     {
303         cin>>v;
304         insertvertex(v);
305     }
306     cout<<"input num(u,v,weight)(弧的数目):";
307     cin>>numv;
308     for(i=1;i<=numv;i++)
309     {
310         cout<<"u->v,weight:";
311         cin>>u>>v>>weight;
312         insertedge(u,v,weight);
313     }
314     cout<<"graph create finish!"<<endl<<endl;
315     return 0;
316 }
317 graph::~graph()
318 {
319 }
320 
321 int main()
322 {
323     graph g;
324     g.create();
325     elementtype  outd[MaxNumVertex];
326     g.FindDegreeout(outd);
327     int i,selected;
328     cout<<"please select Algorithms:[1[Dijkstra Algorithm];2[Floyd Algorithms];3[Exit]]:"<<endl;
329     cout<<"continue[please input selected]:";
330     while(cin>>selected)
331     {
332         switch(selected)
333         {
334         case 1:
335             for(i=1;i<=g.CurrentVertex;i++)
336             {
337                 if(outd[i]!=0)
338                 {
339                     g.Dijkstra(i);
340                     cout<<endl;
341                 }
342             }
343             cout<<"continue[please input selected]:";
344             break;
345         case 2:
346             g.Floyd();
347             cout<<"continue[please input selected]:";
348             break;
349         case 3:
350             exit(0);
351             break;
352         default:
353             exit(0);
354             break;
355         }
356     }
357     return 0;
358 }

 

 

 

 

 

posted @ 2015-12-03 16:16  指间ゝ繁华初逝的格调  阅读(366)  评论(0编辑  收藏  举报