前提:了解Bellman-Ford算法
基本模型:
#include<iostream>
using namespace std;
#define inf 0x7fffffff
#define maxx 100
int G[maxx][maxx],dis[maxx];
int n,m;
int min(int a,int b)
{
return (a>b?b:a);
}
void init(int n)
{
for(int i=1;i<=n;i++)
{
dis[i]=0;
for(int j=1;j<=n;j++)
G[i][j]=(i==j?0:inf);
}
}
void Bellman_Fory()
{
for(int i=1;i<=n;i++)
dis[i]=G[1][i];
dis[1]=0;
for(int k=2;k<=n;k++)//从dist(1)[i]递推出dist(2)[i],...,dist(n-1)[i]
{
for(int i=1;i<=n;i++)//修改每个顶点的dist[i]
{
if(i!=1)
for(int j=1;j<=n;j++)
{
//顶点j到i有直接途径并且途经顶点j可以使得dist[i]缩短
if(G[j][i]<inf&&dis[i]>dis[j]+G[j][i])
dis[i]=dis[j]+G[j][i];
}
}
}
/*判断是否存在负权值回路
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(G[i][j]<inf&&dis[j]>dis[i]+G[i][j])
return false;
}
return true;
}
*/
}
int main()
{
cin>>n>>m;
int a,b,c;
init(n);
for(int i=1;i<=m;i++)
{
cin>>a>>b>>c;
G[a][b]=c;
}
Bellman_Fory();
for(int i=1;i<=n;i++)
cout<<dis[i]<<" ";
cout<<endl;
}
进一步探讨:
用邻接表实现(复杂度是O(n^2))
#include<iostream>
using namespace std;
#define inf 0x7fffffff
#define maxx 1010
typedef struct Edge
{
int u,v;
int weight;
}Edge;
Edge edge[maxx];
int dist[maxx];
int n,e,s;//结点数,边数,源点
void init()
{
cin>>n>>e>>s;
for(int i=1;i<n;i++)
dist[i]=inf;
dist[s]=0;
for(int i=1;i<=e;i++)
{
cin>>edge[i].u>>edge[i].v>>edge[i].weight;
if(edge[i].u==s)
dist[edge[i].v]=edge[i].weight;
}
}
bool Bellman_Ford()
{
for(int i=1;i<=n-1;i++)
for(int j=1;j<=n;j++)
if(edge[j].weight<inf&&dist[edge[j].v]>dist[edge[j].u]+edge[j].weight)
dist[edge[j].v]=dist[edge[j].u]+edge[j].weight;
bool flag = 1;
for(int i=1;i<e;i++)
if(edge[j].weight<inf&&&&dist[edge[i].v]>dist[edge[i].u]+edge[i].weight)
{
flag = 0;
break;
}
return flag;
}
int main()
{
init();
if(Bellman_Ford())
for(int i=1;i<=n;i++)
cout<<dist[i]<<endl;
else
cout<<"No"<<endl;
return 0;
}
测试样例:
7 10
1 2 6
1 3 5
1 4 5
2 5 -1
3 2 -2
3 5 1
4 3 -2
4 6 -1
5 7 3
6 7 3