您的位置:首页 > 其它

单源最短路径 Dijkastra算法

2011-09-01 10:30 176 查看
给定带权有向图G =(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点,称为源。现在要计算从源到所有其它各顶点的最短路长度。这里路的长度是指路上各边权之和。这个问题通常称为单源最短路径问题。


1、算法基本思想

Dijkstra(迪杰斯特拉)算法是解单源最短路径问题的贪心算法。

其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。

初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组m记录当前每个顶点所对应的最短特殊路径长度。Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组m作必要的修改。一旦S包含了所有V中顶点,m就记录了从源到所有其它顶点之间的最短路径长度。(/article/5116379.html

如下图所示:



代码如下:

#include <iostream>
#include <fstream>
using namespace std;

ifstream fin("in.txt");
#define LL 20
int a[LL][LL];
bool visited[LL];
int m[LL];

void Dijkastra(int n)
{
int i,j,min,t;
visited[0]=true;
m[0]=0;
int count = 1;
int last = 0;
while(count < n)
{
min = t = 10000;
for(j=1;j<n;j++)
{
if( !visited[j])
{
if(a[last][j])
{
t =a[last][j]+m[last];
if(t<m[j] || m[j]==0) m[j]=t;
}
if(m[j]<min && m[j]!=0){min=m[j];i=j;}
cout<<"j:"<<j<<" i:"<<i<<" last:"<<last<<" a[last][j]:"<<a[last][j]<<" m[last]:"<<m[last]<<" m[j]:"<<m[j]<<endl;
}
}
cout<<"--- i :"<<i<<"   m[i]:"<<min<<endl;
visited[i]=true;
last=i;
m[last]=min;
count++;
}
return;
}

int main()
{
int n;
fin>>n;
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
fin>>a[i][j];
}
}
memset(visited,0,sizeof(int)*LL);
memset(m,0,sizeof(int)*LL);
Dijkastra(n);
for(i=1;i<n;i++)
{
cout<<"1-->"<<i+1<<" : "<<m[i]<<endl;
}
return 0;
}


输入文件: in.txt

5(第一个)

0 10 0 30 100

0 0 50 0 0

0 0 0 0 10

0 0 20 0 60

0 0 0 0 0

5(第二个)

0 4 2 0 0

0 0 3 2 3

0 1 0 4 5

0 0 0 0 0

0 0 0 1 0

输出结果:

(第一个)



(第二个)

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