多段图的最短路径 图问题中的动态规划法(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

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值