图的单源最短路径算法

第1关:求图(邻接矩阵存储)最短路径的狄克斯特拉算法

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h>
#include<limits.h>  
#include<iostream>
using namespace std;
#include"MGraph.h"


void Dijkstra(MGraph g,int v);        //求从v到其他顶点的最短路径
void DispAllPath(MGraph &g,int dist[],int path[],int S[],int v) ;//输出从顶点v出发的所有最短路径
void Dispdistpath(int dist[],int path[],int n);    //输出dist数组和path数组

int main()
{
    MGraph g;
    int i,j,n;
    CreateGraphF(g);           /* 利用数据文件创建有向图*/
    Display(g);    /* 输出有向图*/  
    Dijkstra(g,0);    
    return 0;
}

void Dijkstra(MGraph g,int v)        
{    
    //求从v到其他顶点的最短路径
    /********** Begin **********/
    int min,num,dist[MAX_VERTEX_NUM],path[MAX_VERTEX_NUM],s[MAX_VERTEX_NUM];
    for(int i = 0; i < g.vexnum; i++)
    {
        dist[i] = g.arcs[v][i].adj;
        if(dist[i]!=INFINITY)
        {
            path[i] = v;
        }else{
            path[i]  = -1;
        }
    }
    for(int i = 0; i < g.vexnum; i++) s[i] = 0;
    {
        s[v] = 1;
    }
    num = 1;
    while(num<g.vexnum)
    {
        int mini = INFINITY,m;
        for(int i = 0; i < g.vexnum; i++)
        {
            if(s[i]==0&&dist[i]<mini)
            {
                mini = dist[i];
                m = i ;
            }
        }
        s[m] = 1;
         Dispdistpath(dist,path,g.vexnum);
        for(int i = 0; i < g.vexnum; i++)
        {
           
            if(s[i] == 0 && (dist[i] > dist[m] + g.arcs[m][i].adj))
            {
                dist[i] = dist[m] + g.arcs[m][i].adj;
                path[i] = m;
            }
        }
        num++;
    }
     Dispdistpath(dist,path,g.vexnum);
    DispAllPath(g,dist,path,s,v);
    /********** End **********/
}

void DispAllPath(MGraph &g,int dist[],int path[],int S[],int v) //输出从顶点v出发的所有最短路径
{
    int i,j,k,count=0;
    int apath[MAX_VERTEX_NUM],d;                //存放一条最短路径(逆向)及其顶点个数
    for (i=0;i<g.vexnum;i++)
        if (path[i]!=-1)
            count++;
    if (count==1)                        //path中只有一个不为-1时表示没有路径
    {    printf("从指定的顶点到其他顶点都没有路径!!!\n");
        return;
    }
    for (i=0;i<g.vexnum;i++)                    //循环输出从顶点v到i的路径
        if (S[i]==1 && i!=v)
        {
            //printf("从%s到%s最短路径长度为:%s\t路径:",g.vexs [v],g.vexs[i],dist[i]);
            cout<<"从"<<g.vexs [v]<<"到"<<g.vexs[i]<<"最短路径长度为:"<<dist[i]<<"\t";
            d=0;             apath[d]=i;            //添加路径上的终点
            k=path[i];
            if (k==-1)                    //没有路径的情况
                printf("无路径\n");
            else                        //存在路径时输出该路径
            {    while (k!=v)
                {    d++; apath[d]=k;
                    k=path[k];
                }
                d++; apath[d]=v;        //添加路径上的起点
                //printf("%d",apath[d]);    //先输出起点
                cout<<g.vexs [ apath[d] ];
                for (j=d-1;j>=0;j--)    //再输出其他顶点
                    //printf("→%d",apath[j]);
                    cout<<"→"<<g.vexs [ apath[j] ];
                printf("\n");
            }
        }
}


void Dispdistpath(int dist[],int path[],int n)    //输出dist数组和path数组
{
    int i;
    printf("dist:\t");
    for (i=0;i<n;i++)
        if (dist[i]==INFINITY)
            printf("%s\t","∞");
        else
            printf("%d\t",dist[i]);
    printf("\n");
    printf("path:\t");
    for (i=0;i<n;i++)
        printf("%d\t",path[i]);
    printf("\n");
}

第2关:求图(邻接表存储)最短路径的狄克斯特拉算法

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h>
#include<limits.h>  
#include<iostream>
using namespace std;

#define INFINITY 4270000 // 用整型最大值代替∞ 
#include"ALGraph.h"

int GetWeight(ALGraph G,VertexType a,VertexType b );//获取权值

void Dijkstra(ALGraph g,int v);        //求从v到其他顶点的最短路径
void DispAllPath(ALGraph &g,int dist[],int path[],int S[],int v) ;//输出从顶点v出发的所有最短路径
void Dispdistpath(int dist[],int path[],int n);    //输出dist数组和path数组

int main()
{
    ALGraph g;
    int i,j,n;
    CreateGraphF(g);           /* 利用数据文件创建有向图*/
    Display(g);    /* 输出有向图*/  
    Dijkstra(g,0);    
    return 0;
}

void Dijkstra(ALGraph g,int v)        
{
    //求从v到其他顶点的最短路径
    /********** Begin **********/
    int min,num,dist[MAX_VERTEX_NUM],path[MAX_VERTEX_NUM],s[MAX_VERTEX_NUM];
    int i;
    for(i = 0; i < g.vexnum; i++)
    {
        dist[i] = GetWeight(g,g.vertices[v].data,g.vertices[i].data);
        if(dist[i]!=INFINITY)
        {
            path[i] = v;
        }
        else
        {
            path[i]  = -1;
        }
    }
   
    for(i = 0; i < g.vexnum; i++)  
    {
        s[i]=0;
        s[v] = 1;
    }
    num = 1;
    while(num<g.vexnum)
    {
        int mini = INFINITY,m;
        for(i = 0; i < g.vexnum; i++)
        {
            if(s[i]==0&&dist[i]<mini)
            {
                mini = dist[i];
                m = i ;
            }
        }
        s[m] = 1;
        Dispdistpath(dist,path,g.vexnum);
        for(i = 0; i < g.vexnum; i++)
        {
           
            if(s[i] == 0 && (dist[i] > dist[m] + GetWeight(g,g.vertices[m].data,g.vertices[i].data)))
            {
                dist[i] = dist[m] + GetWeight(g,g.vertices[m].data,g.vertices[i].data);
                path[i] = m;
            }
        }
        num++;
    }
     Dispdistpath(dist,path,g.vexnum);
     DispAllPath(g,dist,path,s,v);

    /********** End **********/
}

void DispAllPath(ALGraph &g,int dist[],int path[],int S[],int v) //输出从顶点v出发的所有最短路径
{
    int i,j,k,count=0;
    int apath[MAX_VERTEX_NUM],d;                //存放一条最短路径(逆向)及其顶点个数
    for (i=0;i<g.vexnum;i++)
        if (path[i]!=-1)
            count++;
    if (count==1)                        //path中只有一个不为-1时表示没有路径
    {    printf("从指定的顶点到其他顶点都没有路径!!!\n");
        return;
    }
    for (i=0;i<g.vexnum;i++)                    //循环输出从顶点v到i的路径
        if (S[i]==1 && i!=v)
        {
            //printf("从%s到%s最短路径长度为:%s\t路径:",g.vexs [v],g.vexs[i],dist[i]);
            cout<<"从"<<g.vertices  [v].data <<"到"<<g.vertices [i].data <<"最短路径长度为:"<<dist[i]<<"\t";
            d=0;             apath[d]=i;            //添加路径上的终点
            k=path[i];
            if (k==-1)                    //没有路径的情况
                printf("无路径\n");
            else                        //存在路径时输出该路径
            {    while (k!=v)
                {    d++; apath[d]=k;
                    k=path[k];
                }
                d++; apath[d]=v;        //添加路径上的起点
                //printf("%d",apath[d]);    //先输出起点
                cout<<g.vertices  [ apath[d] ].data ;
                for (j=d-1;j>=0;j--)    //再输出其他顶点
                    //printf("→%d",apath[j]);
                    cout<<"→"<<g.vertices  [ apath[j] ].data ;
                printf("\n");
            }
        }
}


void Dispdistpath(int dist[],int path[],int n)    //输出dist数组和path数组
{
    int i;
    printf("dist:\t");
    for (i=0;i<n;i++)
        if (dist[i]==INFINITY)
            printf("%s\t","∞");
        else
            printf("%d\t",dist[i]);
    printf("\n");
    printf("path:\t");
    for (i=0;i<n;i++)
        printf("%d\t",path[i]);
    printf("\n");
}

int GetWeight(ALGraph G,VertexType a,VertexType b )//获取权值 
{    int pa,pb;
    pa=LocateVex(G,a);
    pb=LocateVex(G,b);
    ArcNode* p;
    p=G.vertices[pa].firstarc;
    if(pa == pb)
        return 0;
    while(p!=NULL)
    {    if( p->data.adjvex  == pb)
        return p->data.info;
        else
        p=p->nextarc;
    }
    return INFINITY;
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ଲଇଉକ ଲ ̊ଳ

多谢大哥赏赐

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值