题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544
解题思路:bellman_Ford算法重写这道题目,该算法是解决有向图的常用算法,与dijkstra算法相比,优点是图中可以存在负边,并且可以检测出是否为负值的环
其解题的一般步骤:
第一,初始化所有点。每一个点保存一个值,表示从原点到达这个点的距离,将原点的值设为0,其它的点的值设为无穷大(表示不可达)。
第二,进行循环,循环下标为从1到n-1(n等于图中点的个数)。在循环内部,遍历所有的边,进行松弛计算。
第三,遍历途中所有的边(edge(u,v)),判断是否存在这样情况:d(v) > d (u) + w(u,v)则返回false,表示途中存在从源点可达的权为负的回路。
在这道题中由于题目说明是可达的,并且距离一定大于0 ,不存在负边,所以没进行第三步操作:
代码:
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,flag,dis[10005],mp[105][105];
const int maxn = 0xfffffff;
int a[10005],b[10005],c[10005];
void bellman_ford()
{
for(int i=1;i<=n;i++)
dis[i]=maxn;
dis[1]=0;
for(int i=1;i<n;i++)
for(int j=1;j<=m;j++)
{
if(dis[b[j]] > dis[a[j]]+mp[a[j]][b[j]])
dis[b[j]]= dis[a[j]] + mp[a[j]][b[j]];
if(dis[a[j]] > dis[b[j]]+mp[b[j]][a[j]])
dis[a[j]] = dis[b[j]]+mp[b[j]][a[j]];
}
}
void init()
{
for(int i=1;i<=n;i++)
{
mp[i][i]=0;
for(int j=i+1;j<=n;j++)
{
mp[i][j]=mp[j][i]=maxn;
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)&&(n||m))
{
init();
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a[i],&b[i],&c[i]);
if(mp[a[i]][b[i]] > c[i])
mp[a[i]][b[i]] = mp[b[i]][a[i]] = c[i];
}
flag=1;
bellman_ford();
if(flag) printf("%d\n",dis[n]);
}
return 0;
}