程序说明:
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
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
Dijkstra(
int
n,
int
v,
int
dist[],
int
prev[],
int
**
c)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{ //单源最短路径的dijkstra算法
int maxint=65535; //设置不可达的路为65535
if(v<1||v>n) return;
bool *s=new bool[n];
for(int i=1;i<=n;i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{ //初始化
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++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
int temp=maxint;
int u=v;
for(int j=1;j<=n;j++)
if((!s[j])&&(dist[j]<temp))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
u=j;
temp=dist[j];
}
s[u]=true;
for(j=1;j<=n;j++)
if((!s[j])&&(c[u][j]<maxint))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
int newdist=dist[u]+c[u][j];
if(newdist<dist[j])
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{ //dist[j]减少
dist[j]=newdist;
prev[j]=u;
}
}
}delete s;
}
void
main()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
cout<<"********************************************************* "<<endl;
cout<<"* 实验三:单源最短路径算法 * "<<endl;
cout<<"********************************************************* "<<endl;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
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++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
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]中
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
q++;
way[q]=prev[w];
w=prev[w];
}
for(j=q;j>=1;j--) //输出路径节点
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
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...
*/