您的位置:首页 > 理论基础 > 数据结构算法

数据结构-图的单源最短路径问题

2015-12-21 10:41 375 查看
定义:从某个源点到其他各顶点的最短路径就是单源最短路径.

Dijkstra算法求单源最短路径的基本思路就是:

搜索以源点为中心,搜索最近的顶点,然后再以最近的顶点为中心,搜索最近的顶点,同时更新最短路径.如此反复.

变量说明:

1. dist[v]:表示从源点s到顶点v的最短路径长度;

dist[s]明显是0;;

与s直接相连的顶点,dist[v]就是边的权重;

与s不是直接相连的顶点,dist[v]是∞;

#include<iostream>
using namespace  std;
#define MAX 10
//===================栈===========================
struct Stack{
int data[MAX];
int top;
};
void Init(Stack& s)
{
s.top=-1;
}
int IsEmpty(const Stack& s)
{
if(s.top<0)
return 1;
return 0;
}
void Push(int x,Stack& s)
{
if(s.top>=MAX){
cout<<"Stack is full!"<<endl;
return ;
}
++s.top;
s.data[s.top]=x;
}
int Pop(Stack& s)
{
if(!IsEmpty(s))
return s.data[s.top--];
else
return -1;
}
//================创建邻接矩阵(有向带权)====================
int CreateGraph(int cost[][MAX])
{
int ver_num,arc_num,v1,v2,w;
cout<<"请输入顶点数,边数:";
cin>>ver_num>>arc_num;
//有向图初始化9999表示无穷大
for(int i=1;i<=ver_num;i++)
for(int j=1;j<=ver_num;j++)
cost[i][j]=9999;

for(int i=1;i<=arc_num;i++){
cout<<"v1,v2,w=";
cin>>v1>>v2>>w;
cost[v1][v2]=w;
}
return ver_num;
}
//================Dijkstra算法===========================
/*按路径长度递增顺序产生最短路径的Dijkstre算法*/
void Dijkstra(int cost[][MAX],int ver_num)
{
int path[MAX],visited[MAX],dist[MAX],w,min,v1;
cout<<"输入源点v1:";cin>>v1;
/*整理初始化*/
for(int i=1;i<=ver_num;i++){
dist[i]=cost[v1][i];//dist初始化
visited[i]=0;//visited初始化
path[i]=-1;
//cost初始化为9999,如果<9999表明有路径
if(cost[v1][i]<9999)
path[i]=v1;//path初始化
}
visited[v1]=true;//标记源点已经访问过了
for(int i=1;i<=ver_num;i++){
min=9999;
//以源点为中心,找与源点直接相连的路径最短的顶点w,并加入已访问过
for(int j=1;j<=ver_num;j++){
//if没有访问过&&不是最短路径
if(visited[j]==0&&dist[j]<min){
min=dist[j];
w=j;
}
}
visited[w]=true;//将w标记访问过
//找到w之后,再以w为顶点,寻找经过w的最短路径
//同时对于所有未收录顶点,更新dist
for(int k=1;k<=ver_num;k++){
if(visited[k]==0){
if(dist[w]+cost[w][k]<dist[k]){
dist[k]=dist[w]+cost[w][k];//更新dist
path[k]=w;//记录前驱
}
}
}
}
//用栈输出path
Stack S;Init(S);
for(int i=2;i<=ver_num;i++){
if(path[i]!=-1){    //防止无路径的输出
Push(path[i],S);
int temp=path[i];
while(temp!=v1){
Push(path[temp],S);
temp=path[temp];
}
while(!IsEmpty(S)){
temp=Pop(S);
cout<<temp<<"==>";
}
cout<<i<<" "<<dist[i]<<endl;
}
}
}
int main()
{
int ver_num;
int cost[MAX][MAX];
ver_num=CreateGraph(cost);
Dijkstra(cost,ver_num);
}


测试:

请输入顶点数,边数:6 11

v1,v2,w=1 2 50

v1,v2,w=1 3 10

v1,v2,w=1 5 45

v1,v2,w=2 3 15

v1,v2,w=2 5 10

v1,v2,w=3 1 20

v1,v2,w=3 4 15

v1,v2,w=4 2 20

v1,v2,w=4 5 35

v1,v2,w=5 4 30

v1,v2,w=6 4 3

输入源点v1:1

1==>3==>4==>2 45

1==>3 10

1==>3==>4 25

1==>5 45
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: