spfa算法详解
http://www.360doc.com/content/13/1208/22/14357424_335569176.shtml
代码详解
#include<iostream>
#include<stdio.h>
#include<vector>
#include<queue>
using namespace std;
#define inf 999999999
typedef struct minx
{
int a,d;
}node;
int dis[20005],n;
vector<node>map[20005];
void init()
{
for(int i=1;i<=n;i++)
{
dis[i]=inf;
}
}
void spfa()
{
queue<int>q;
int book[20005]={0},t;
q.push(1);
book[1]=1;
dis[1]=0;
while(!q.empty())
{
t=q.front();
q.pop();
book[t]=0;
int len=map[t].size(),a;
for(int i=0;i<len;i++)
{
a=map[t][i].a;
if(dis[a]>map[t][i].d+dis[t])
{
dis[a]=map[t][i].d+dis[t];
if(!book[a])
{
book[a]=1;
q.push(a);
}
}
}
}
}
int main()
{
int m,a,b,l;
node Now;
while(~scanf("%d %d",&n,&m))
{
init();
while(m--)
{
scanf("%d %d %d",&a,&b,&l);
Now.a=b,Now.d=l;
map[a].push_back(Now);
}
spfa();
for(int i=2;i<=n;i++)
printf("%d\n",dis[i]);
}
return 0;
}
dijkstra算法,会超时,且只能用于边为正的
memset(book,0,sizeof book);
for(i=2;i<=n;i++)
d[i]=inf;
d[1]=0;
for(i=1;i<=n;i++)
{
int x,m=inf;
for(j=1;j<=n;j++)
{
if(!book[j]&&d[j]<=m)
m=d[x=j];
}
book[x]=1;
for(j=0;j<=n;j++)
{
d[j]=min(d[j],d[x]+e[x][j]);
}
}
Floyd算法
for(int k=0;k<n;k++)
for(int i=0;i<n;k++)
for(int j=0;j<n;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
Bellman-Ford算法
http://blog.csdn.net/guixunlong/article/details/8474263
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAX 9999999
typedef struct
{
int u,v,cost;
}Edge;
Edge edge[200001];
int pre[200001];
int dis[200001];
int m,n;
int original;
bool bellman_ford()
{
for(int i=2;i<=n;i++)
dis[i]=MAX;
for(int i=1;i<=n-1;i++)
for(int j=1;j<=m;j++)
if(dis[edge[j].v]>dis[edge[j].u]+edge[j].cost)
{
dis[edge[j].v]=dis[edge[j].u]+edge[j].cost;
pre[edge[j].v]=edge[j].u;
}
bool flag=true;
//bellman-ford的一个优势是可以用来判断是否存在负环的在不存在负环的情况下,进行了n-1次所有边的更新
//操作后每个结点的最短路径都确定了,在用所有边去更新一次不会改变结果的。如果存在负环,最后再更新一次会改变结果
//原因是之前是假定了起点的最短路距离是确定的并且是最短的
//而有负环的情况下这个假设不再成立
//
for(int i=1;i<=m;i++)
{
if(dis[edge[i].v]>dis[edge[i].u]+edge[i].cost)
{
flag=false;
break;
}
}
return flag;
}
int main()
{
while(cin>>n>>m)
{
pre[1]=0;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].cost);
}
if(bellman_ford())
{
for(int i=2;i<=n;i++)
cout<<dis[i]<<endl;
}
}
return 0;
}
三个算法的分析
http://blog.csdn.net/mmy1996/article/details/52225893