单源最短路径算法

程序说明:
 1:输入图G的顶点数n。
 2:接着输入一个n*n的数组来描述这一个图形,采用邻接表方式,
    其中第i行有n个数,依次表示第i个顶点与第1、2、3、…、n个顶点间的路径长度。
    假如两个顶点间无边相连,用一个大数maxint(如65535)表示。
 3:给出两个整数V、U表示要求最短距离的起始顶点V和终止顶点U。
 4:输出两个顶点V和顶点U的最短距离,同时给出最短路径上的顶点序列。
 注意:每行上的两个相邻数间用一个空格隔开。
算法描述:
  Dijkstra算法大概描述如下:其中输入的带权有向图是G=(V,E),V={1,2,…,N}。
 顶点V是源。c是一个二维数组,c[i][j]表示边(i,j)的权,当(i,j)不属于E时,c[i][j]是一个大数。
 dist[u]表示当前从源到顶点u的最短特殊路径长度。
  对于具有n个顶点和e条边的带权有向图,如果用带权邻接矩阵表示这个图,
 那么Dijkstra算法的主循环体需要O(n)时间。这个循环需要执行n-1次,
 所以完成循环需要O(n2)时间。算法的其余部分所需要时间不超过O(n2)。

#include < iostream.h >

void  Dijkstra( int  n, int  v, int  dist[], int  prev[], int   ** c)
{                                            //单源最短路径的dijkstra算法
    int maxint=65535;                        //设置不可达的路为65535
    if(v<1||v>n) return;
    
bool *s=new bool[n];
    
for(int i=1;i<=n;i++)
    
{                                        //初始化
        dist[i]=c[v][i];
        s[i]
=false;
        
if(dist[i]==maxint)prev[i]=0;
        
else prev[i]=v;
    }

    dist[v]
=0;
    s[v]
=true;
    
for(i=1;i<n;i++)
    
{
        
int temp=maxint;
        
int u=v;
        
for(int j=1;j<=n;j++)
            
if((!s[j])&&(dist[j]<temp))
            
{
                u
=j;
                temp
=dist[j];
            }

            s[u]
=true;
            
for(j=1;j<=n;j++)
                
if((!s[j])&&(c[u][j]<maxint))
                
{
                    
int newdist=dist[u]+c[u][j];
                    
if(newdist<dist[j])
                    
{                        //dist[j]减少
                        dist[j]=newdist;
                        prev[j]
=u;
                    }

                }

    }delete s;

}

void  main()
{
    
    cout
<<"********************************************************* "<<endl;
    cout
<<"*              实验三:单源最短路径算法                 * "<<endl;
    cout
<<"********************************************************* "<<endl;

    
int n,v,u;
    
int q=0;
    cout
<<"输入图G的顶点数n:";
    cin
>>n;
    
int *way=new int[n+1];                        //way[i]用于记录路径
    int **c=new int *[n+1];                        
    
for(int i=1;i<=n;i++)
    
{
        c[i]
=new int[n+1];
    }

    cout
<<"输入边[i][j]的权值:"<<endl;
    
for(int j=1;j<=n;j++)                        //初始化有向边的权值
        for(int t=1;t<=n;t++)
            cin
>>c[j][t];
        
int *dist=new int [n];
        
int *prev=new int [n];
        cout
<<"请输入你选择的源V和终点U:"<<endl;
        cin
>>v>>u;
        Dijkstra(n,v,dist,prev,c);                
//用Dijkstra算法计算最短路径
        cout<<"算法得出从"<<v<<" -> "<<u<<" 的最短路径距离是 "<<dist[u]<<endl;
        cout
<<"具体路径是:";
        
int w=u;
        
while(w!=v)                                //计算前驱顶点,并保存在way[i]中
        {
            q
++;
            way[q]
=prev[w];
            w
=prev[w];
        }

        
for(j=q;j>=1;j--)                        //输出路径节点
        {
            cout
<<way[j]<<" ->";
        }

        cout
<<u<<endl; deltet way;delete c;delete dist;delete prev;
}

/*
实验结果:

*********************************************************
*              实验三:单源最短路径算法                 *
*********************************************************
输入图G的顶点数n:5
输入边[i][j]的权值:
0 10 65535 30 100
65535 0 50 65535 65535
65535 65535 0 65535 10
65535 65535 20 0 60
65535 65535 65535 65535 0
请输入你选择的源V和终点U:
1 5
算法得出从1 -> 5 的最短路径距离是 60
具体路径是:1 ->4 ->3 ->5
Press any key to continue...

*/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值