Bellman-Ford 的动态规划实现

思考这个算法已经两天了。之前发过一个Bellman-Ford算法,但那一个使用的是收缩法,十分耗费时间。于是开始尝试动态规划,代码如下,已经可以解决有负值时的求解最短路径,但是没有处理负圈的功能。因为我没有能力在动态规划的递归函数中进行负圈的判断(个人感觉Algorithm design 中“n-1!=n”一说有误)。如果在递归外部判断,那么该方法就失去了相对于收缩法的优势,时间复杂度将相等。所以那位大神可以在递归函数中判断负圈,请不吝赐教。当然Bellman-Ford算法并不是解决这个问题的最佳算法,但是为了练习动态规划,我还是花费了许多时间。

Have fun coding,i_human.Have fun coding,everyone!

THE CODE:

// Bellman-Ford solved by dynamic prgramming.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#define N 100
#define m 10000  //当作正无穷使用

using namespace std;

int find(int i,int t);
void prin();

int n,e,l;
int pre[2][N];
int edge[N][N];

int main()
{
	int u,v,length;
	cin>>n>>e;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			edge[i][j]=m;
		}
	}
	for(int i=1;i<=n;i++)
	{
		pre[0][i]=-1;
		pre[1][i]=m;
	}
	pre[0][1]=1;	//以1作为源点
	pre[1][1]=0;
	for(int i=0;i<e;i++)
	{
		cin>>u>>v>>length;
		edge[u][v]=length;
	}
	for(int k=2;k<=n;k++)
		find(e,k);		
	prin();
	system("pause");
	return 0;
}

int find(int i,int t)
{
	if(pre[0][t]!=-1 && t!=1)
		return find(i-1,pre[0][t])+pre[1][t];
	else if(t==1)
		return 0;
	else
	{
		int M=m;
		for(int j=1;j<=n;j++)
		{
			if(edge[j][t]!=m && find(i-1,j)+edge[j][t]<M)
			{
				M=find(i-1,j)+edge[j][t];
				l=j;
			}
		}
		pre[0][t]=l;
		pre[1][t]=edge[l][t];
		return find(i-1,l)+edge[l][t];
	}
}

void prin()
{
	for(int i=2;i<=n;i++)
	{
		cout<<i<<"<--";
		int j=pre[0][i];
		while(j!=1)
		{
			cout<<j<<"<--";
			j=pre[0][j];
		}
		cout<<"1"<<endl;
	}
}
    原文作者:动态规划
    原文地址: https://blog.csdn.net/i_human/article/details/52642099
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞