头歌——基于Dijsktra算法的最短路径求解

#include<iostream>

#define MAXSIZE 100

#define OK 1

#define ERROR 0

#define OVERFLOW -2

#define MaxInt 32767                        //表示极大值,即∞

#define MVNum 100

using namespace std;

typedef struct

{

    char vexs[MVNum];                   //顶点表

    int arcs[MVNum][MVNum];               //邻接矩阵

    int vexnum;                           //图的总顶点数

    int arcnum;                        //图的总边数

} AMGraph;

int LocateVex(AMGraph G,char u)

{//存在则返回u在顶点表中的下标,否则返回ERROR

    int i;

    for (i = 0; i < G.vexnum; ++i)

        if (u == G.vexs[i])

            return i;

    return -1;

}

char OrigialVex(AMGraph G,int u)

{//存在则返回顶点表中下标为u的元素

    return G.vexs[u];

}

int CreateDN(AMGraph &G,int spot,int edge)

{//采用邻接矩阵表示法,创建有向网G

    //cin>>G.vexnum;  //输入总顶点数

    //cin>>G.arcnum;    //输入总边数

    G.vexnum=spot;

    G.arcnum=edge;

    int i,j,k,w;

    char v1,v2;

    for(i = 0; i<G.vexnum; ++i)    

      cin>>G.vexs[i];                           //依次输入点的信息

    for(i = 0; i<G.vexnum;++i)  //初始化邻接矩阵,边的权值均置为极大值

       for(j = 0; j<G.vexnum;++j)  

         G.arcs[i][j] = MaxInt;  

    for(k = 0; k<G.arcnum;++k){                     //构造邻接矩阵

      cin>>v1>>v2>>w;                                 //输入一条边依附的顶点及权值

      i = LocateVex(G, v1);  j = LocateVex(G, v2);  //确定v1和v2在G中的位置

      G.arcs[i][j] = w; //边<v1, v2>的权值置为w  

   }//for

   return OK;

}

void ShortestPath_DIJ(AMGraph G, char V,int * Path,int * D)

{//用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径

    int i,n,v,min,w;

    int S[MVNum];

    n=G.vexnum;                         //n为G中顶点的个数

    int v0=LocateVex(G,V);

    for(v = 0; v<n; ++v)

    {               //n个顶点依次初始化

        S[v] = false;                   //S初始为空集

        D[v] = G.arcs[v0][v];               //将v0到各个终点的最短路径长度初始化

        if(D[v]< MaxInt)  

            Path [v]=v0; //v0和v之间有弧,将v的前驱置为v0

        else

            Path [v]=-1;                //如果v0和v之间无弧,则将v的前驱置为-1

    }//for

    S[v0]=true;                     //将v0加入S

    D[v0]=0;                            //源点到源点的距离为0

    /*―开始主循环,每次求得v0到某个顶点v的最短路径,将v加到S集―*/

    for(i=1;i<n; ++i)

    {                   //对其余n−1个顶点,依次进行计算

        min= MaxInt;

        for(w=0;w<n; ++w)

            if(!S[w]&&D[w]<min)  

            {

                v=w; min=D[w];

            }           //选择一条当前的最短路径,终点为v

            S[v]=true;                          //将v加入S

            for(w=0;w<n; ++w)   //更新从v0出发到集合V−S上所有顶点的最短路径长度

                if(!S[w]&&(D[v]+G.arcs[v][w]<D[w])){

                    D[w]=D[v]+G.arcs[v][w];     //更新D[w]

                    Path [w]=v;                     //更改w的前驱为v

                }//if

    }//for

    //for(int i=0;i<n;i++)

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

    //cout<<endl;

}

void Find(AMGraph G,int v,int * Path)

{//在Path数组中查找序号v

    int n=G.vexnum;

    if(Path[v]==-1||v==-1)

        return;

    else

    {

        Find(G,Path[v],Path);

        cout<<OrigialVex(G,Path[v])<<" ";

    }

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值