1261:【例9.5】城市交通路网(动态规划)

城市交通路网
题目描述

下图表示城市之间的交通路网,线段上的数字表示费用,单向通行由A->E。试用动态规划的最优化原理求出A->E的最省费用。
在这里插入图片描述
如图:求v1到v10的最短路径长度及最短路径。
【输入】
第一行为城市的数量N;

后面是N*N的表示两个城市间费用组成的矩阵。
【输出】

A->E的最省费用。
【输入样例】

10
0  2  5  1  0  0  0  0  0  0
0  0  0  0 12 14  0  0  0  0
0  0  0  0  6 10  4  0  0  0
0  0  0  0 13 12 11  0  0  0
0  0  0  0  0  0  0  3  9  0
0  0  0  0  0  0  0  6  5  0
0  0  0  0  0  0  0  0 10  0
0  0  0  0  0  0  0  0  0  5
0  0  0  0  0  0  0  0  0  2
0  0  0  0  0  0  0  0  0  0

【输出样例】

minlong=19
1 3 5 8 10
解题思路

dp[i]的含义:第i个城市到第一个城市之间的最短距离。

if (dp[i] > dp[j] + mp[j][i])
dp[i] = dp[j] + mp[j][i];

这个地方很关键,如果第i个城市到第一个城市之间的距离大于第j个城市到第一个城市的距离+第i个城市和第j个城市之间的距离,那么就更新dp[i],这样下去,最后得到的就是第n个城市到第一个城市之间距离的最小值。
下图是每一次更新时的情况。

在这里插入图

代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1010;
int mp[N][N];
int dp[N] ;
int arr[N];
int ans[N];
int main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
			cin >> mp[i][j];
	}
	for (int i = 2; i <= n; i++)
		dp[i] = N;//初始化
	for (int i = 2; i <= n; i++)
	//从第二个城市开始
	{
		for (int j = 1; j <= n; j++)
		{
			if (mp[j][i] != 0)
			{
				if (dp[i] > dp[j] + mp[j][i])
				{
					dp[i] = dp[j] + mp[j][i];
					/*cout << "dp[" << i << "]" <<" = dp["<<j<<"]"<<" + mp["<<j<<"]"<<"["<<i<<"]"<< endl;
					cout << dp[i] << " = " << dp[j] << " + " << mp[j][i] << endl;*/
					arr[i] = j;
					//用arr来保存每一次改变时候的城市j
				}
			}
		}
	}
	cout <<"minlong="<< dp[n] << endl;
	int k = n,t=1;//k从大到小
	while (k >= 1)
	{
		ans[t++] = k;
		k = arr[k];
		//由于直接输出方向相反,所以将每最小距离时的每一个城市放在ans里面
	}
	for (int i = t-1; i >=1 ; i--)
		cout << ans[i] << " ";
	return 0;
}
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值