图的最短路径算法

1、问题描述

给定一个顶点(始点),求该顶点(始点)到(连通)图中其它顶点的最短路径。

 

2、算法

⑴、初始化: S ← {v1 };                               // 始点送S

D[i] ← arc[1][i],   i = 2, 3, …, n;               // 从v1到vi的距离

P[i] = {1,i}                                        //从v1到vi的路径

⑵、求出最短路径的长度:

D[j] ← min { D[i] },  iÎV-S; S←S U{j };

⑶、修改: 

if (D[i] > D[j] +arc[j][i]) {

D[i] =D[j]+arc[j][i];

P[i] = P[j] U {i}; }   iÎV-S                  // 更新从v1到vi的路径

⑷、判断:若 S = V, 则算法结束,否则转 ⑵。

 

3、输入

第一行:样本顶点个数,假设为n。

第二行,n个顶点(用空格隔开)

第三行开始到n+2行:每一行是某顶点(按第二行的输入为序)与其它顶点的距离(-1表示无穷大)

第n+3行:开始顶点

 

 

4、输入样本

5

a b c d e

-1 5 -1 7 15

-1 -1 5 -1 -1

-1 -1 -1 -1 1

-1 -1 2 -1 -1

-1 -1 -1 -1 -1

a

 

5、输出

共计n行(图中顶点数目)

每行是(与输入顺序相同)某顶点(距离):路径(顶点序列,用空格隔开,回车前无空格)

 

6、输出样本

a(0):

b(5): a b

c(9): a d c

d(7): a d

e(10): a d c e


#include <iostream>

using namespace std;


const int MAX_VERT = 20;

const int MAX_NUM = 1000;


bool final[MAX_VERT];

int Dest[MAX_VERT];

char Path[MAX_VERT][MAX_VERT];


struct Graphic{

       int vertNum;

       charvertValue[MAX_VERT];

       intAdjMatrix[MAX_VERT][MAX_VERT];

};


void initGraphic(Graphic &G, int n){

       int i, j;

       G.vertNum = n;


       for(i = 1; i <=G.vertNum; i++)

              cin>>G.vertValue[i];

      

       for(i = 1; i <=G.vertNum; i++){

              for(j = 1; j<= G.vertNum; j++){

                     cin>>G.AdjMatrix[i][j];

                     if(G.AdjMatrix[i][j]== -1)

                            G.AdjMatrix[i][j]= MAX_NUM;

              }

       }

}


void shortestPath(Graphic G, char vert){

       int i, j, k, cv, Min;

     

      for(i = 1; i <=G.vertNum; i++){

              if(G.vertValue[i]== vert){

                     cv = i;

                     break;

              }

       }

       //访问集初始化和路径集初始化

       for(i = 1; i <=G.vertNum; i++){

              Path[i][0] = 0;

              Dest[i] =MAX_NUM;

              if(G.AdjMatrix[cv][i]< MAX_NUM){

                     Dest[i] =G.AdjMatrix[cv][i];

                     Path[i][1]= G.vertValue[cv];

                     Path[i][2]= G.vertValue[i];

                     Path[i][0]= 2;

              }

              final[i] = false;

       }

       //

       final[cv] = true;

       Dest[cv] = 0;

       

       for(i = 1; i <G.vertNum; i++){

              Min = MAX_NUM;

              for(j = 1; j<= G.vertNum; j++){

                     if(!final[j]&& Dest[j] < Min){

                            cv= j;

                            Min= Dest[j];

                     }

              }

              final[cv] = true;

         

              for(j = 1; j<= G.vertNum; j++){

                     if((!final[j])&& (Min + G.AdjMatrix[cv][j] < Dest[j])){

                            Dest[j]= Min + G.AdjMatrix[cv][j];

                            for(k= 0; k <= Path[cv][0]; k++){

                                   Path[j][k]= Path[cv][k];   

                            }

                            Path[j][0]++;

                            Path[j][Path[j][0]]= G.vertValue[j];

                     }

              }

       }

       

       for(i = 1; i <=G.vertNum; i++){

              cout<<G.vertValue[i]<<"("<<Dest[i]<<"):";

              for(j = 1; j<= Path[i][0]; j++)

                     cout<<""<<Path[i][j];

              cout<<endl;

       }

}


int main()

{

       int n;

       char ch;

       Graphic G;


  

       //顶点个数

       cin>>n;

       //图的初始化

       initGraphic(G, n);

       //最短路径查找,初始顶点为ch

       cin>>ch;

       shortestPath(G, ch);

       //结束

       return 0;

}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值