有向图图中任何两个可到达的顶点之间最短路径以及相应的长度
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 }