多段图的最短路径 图问题中的动态规划法(C++实现)

问题:设图G=(V,E)是一个带权有向图,多段图的最短路径问题(Multi-segment Graph Shortest Path Problem)求从源点到终点的最小代价路径。

算法:设置cost数组记载当前从原点到该点的最短路径,path数组记录最短路径当前点的前驱。

代码如下:

int ShortestPath(int arc[100][100],int n){
	int i,j,cost[n],path[n];
	cost[0] = 0;path[0] = -1;//顶点0为原点,初始化
	for(j=1;j<n;j++){
		cost[j] = 100;//默认单路径长度不大于100
		for(i=0;i<j;i++){
			if(arc[i][j] > 0){//如果从i到j的边存在
				if(cost[i] + arc[i][j] < cost[j]){//从原点到i的cost加上ij边,与原点到j的边比较
					 cost[j] = cost[i] + arc[i][j];//取路径小的
					 path[j] = i;//j的前驱是i
				}	
			}
		}
	}
	cout<<--n;//最后一个点
	for(i=n;path[i]>=0;){
		cout<<"<--"<<path[i];
		i = path[i];
	}
	cout<<endl;
	return cost[n];//返回最短路径长度
}

构建图:

struct Graph{
	int Vex[100];//顶点
	int arc[100][100];//边的权
	int vexnum,arcnum;//顶点数、边数
};
void InitGraph(Graph &G){
	G.vexnum = G.arcnum = 0;
}
void InsertVex(Graph &G,int v){
	G.Vex[G.vexnum++] = v;
}
int LocateVex(Graph &G,int v){
	for(int i=0;i<=G.vexnum;i++)
		if(v == G.Vex[i])	return i;
	return -1;
}
void InsertEdge(Graph &G,int v1,int v2,int e){
	int v1num = LocateVex(G,v1);
	int v2num = LocateVex(G,v2);
	G.arc[v1num][v2num] = e;
	G.arcnum += 1;
}
void ShowGraph(Graph &G){
	cout<<"代价矩阵:"<<endl;
	cout<<"   ";
	for(int i=0;i<G.vexnum;i++)
		cout<<G.Vex[i]<<"  ";
	cout<<endl;
	for(int i=0;i<G.vexnum;i++){
		cout<<G.Vex[i]<<"  ";
		for(int j=0;j<G.vexnum;j++)	cout<<G.arc[i][j]<<"  ";
		cout<<endl;
	}
	cout<<endl;
}

测试如下:

int main(){
	Graph G;
	InitGraph(G);
	InsertVex(G,0);InsertVex(G,1);InsertVex(G,2);InsertVex(G,3);InsertVex(G,4);
	InsertVex(G,5);InsertVex(G,6);InsertVex(G,7);InsertVex(G,8);InsertVex(G,9);
	InsertEdge(G,0,1,4);InsertEdge(G,0,2,2);InsertEdge(G,0,3,3);
	InsertEdge(G,1,4,9);InsertEdge(G,1,5,8);InsertEdge(G,2,4,6);
	InsertEdge(G,2,5,7);InsertEdge(G,2,6,8);InsertEdge(G,3,5,4);
	InsertEdge(G,3,6,7);InsertEdge(G,4,7,5);InsertEdge(G,4,8,6);
	InsertEdge(G,5,7,8);InsertEdge(G,5,8,6);InsertEdge(G,6,7,6);
	InsertEdge(G,6,8,5);InsertEdge(G,7,9,7);InsertEdge(G,8,9,3);
	ShowGraph(G);
	int cost = ShortestPath(G.arc,10);
	cout<<"最短路径长度为:"<<cost<<endl;
}

输出如下:

代价矩阵:
   0  1  2  3  4  5  6  7  8  9
0  0  4  2  3  0  0  0  0  0  0
1  0  0  0  0  9  8  0  0  0  0
2  0  0  0  0  6  7  8  0  0  0
3  0  0  0  0  0  4  7  0  0  0
4  0  0  0  0  0  0  0  5  6  0
5  0  0  0  0  0  0  0  8  6  0
6  0  0  0  0  0  0  0  6  5  0
7  0  0  0  0  0  0  0  0  0  7
8  0  0  0  0  0  0  0  0  0  3
9  0  0  0  0  0  0  0  0  0  0

9<--8<--5<--3<--0
最短路径长度为:16

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是用C++动态规划多段的起点到终点的最短路径的完整代码: ```cpp #include <iostream> #include <vector> #include <climits> using namespace std; const int MAXN = 100; int matrix[MAXN][MAXN]; int shortestPath(int n, int m) { vector<int> dp(n + 1, INT_MAX); dp[m] = 0; for (int i = m + 1; i <= n; ++i) { for (int j = m; j < i; ++j) { if (matrix[j][i] != INT_MAX) { dp[i] = min(dp[i], dp[j] + matrix[j][i]); } } } return dp[n]; } int main() { int n, m; cin >> n >> m; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { int cost; cin >> cost; if (cost == -1) { matrix[i][j] = INT_MAX; } else { matrix[i][j] = cost; } } } cout << shortestPath(n, m) << endl; return 0; } ``` 在这个代码,我们首先定义了一个常量MAXN表示最大的节点数。然后,定义了一个二维数组matrix来表示多段的代价矩阵。接下来,我们定义了动态规划函数shortestPath,该函数接受两个参数n和m,其n表示多段节点的总数,m表示多段第一段的最后一个节点的编号。在函数内部,我们使用了一个一维数组dp来记录起点到每个节点的最短路径长度,然后从第m+1段开始遍历每个节点,遍历时再从该节点前面的所有段找到一条到达该节点的最短路径。如果存在这样的路径,则更新该节点的最短路径长度。最终,dp[n]就是起点到终点的最短路径长度。在主函数,我们首先读入多段的代价矩阵,然后调用shortestPath函数计算最短路径,并输出结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值