zoukankan      html  css  js  c++  java
  • 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 }

     

  • 相关阅读:
    linux查看与设置主机名
    为什么用户主目录下.bash_profile没有自动执行
    sqlplus查看服务名
    linux之cp/scp命令+scp命令详解
    查看磁盘使用量
    yum源
    微软输入法删除
    Android下 ionic view 无法登录
    inline-block在ie6中的经典bug
    Apache端口配置
  • 原文地址:https://www.cnblogs.com/minmsy/p/5016633.html
Copyright © 2011-2022 走看看