优点:代码较少,复杂度不高,可以判断是否会有负环。
缺点:效率低。
算法阐述:
这个算法的思想非常简单,首先它是根据从起点向与它相连的线段开始刷新,只要满足刷新后的路径比原有路径小的话,那么就立即更新这个数据,是这个数据作为新的数
据。同时这个算法有一个很重要的优势,那就是可以判断有没有负环的存在。
负环判断原理:
这个算法的代码我在下面会有一个代码的描述,这个算法是通过一个整体的更新来实现查找最短的路径,那么这里面就有一个关于这个算法的更新次数的问题,首先一个确定
下来的顶点它向它周围进行一个更新是否会更新出至少一个顶点呢?答案: 是的,如果一个确定的顶点是一定可以更新出另一个确定的顶点的,这里说的确定的顶点就是 这个顶点
有了一个确定的路径的。比如:A->Z 这里面A为起点,如果A起点不能确定与它相连的顶点没有一条为最短的点,那么这个A->Z也就无解了,关于这个问题我就不再阐述了。
代码:
#include <iostream>
#include<cstdio>
using namespace std;
typedef struct Line{
int first;
int last;
int length;
}L;
L a[50];
int d[50];
int main()
{
int n,m,temp;//n为边数,m为顶点数
scanf("%d%d",&n,&m);
fill(d,d+50,8888888);//先将d全部赋值为8888888,这是让他们先当做我还没有定值的顶点!
d[1]=0;//起点置为0
for(int i=0;i<n;i++)scanf("%d%d%d",&a[i].first,&a[i].last,&a[i].length);
for(int i=1;i<=m;i++)
{
temp=1;//用这个变量来判断这个环是否都是最短路径了!
for(int j=0;j<n;j++)
{
if(d[a[j].last]>d[a[j].first]+a[j].length)//判断标准
{
d[a[j].last]=d[a[j].first]+a[j].length;
temp=0;
if(i==m){//上文已经有了一个解释
printf("出现了负环!!!!");
return -1;
}
}
}
if(temp){
break;
}
}
for(int i=1;i<=m;i++)
{
printf("%d\n",d[i]);
}
}