多段图问题(图的邻接表)

/**********************************/
/*          多段图问题            */
/*求源点到汇点的最小花费及最短路径*/
/**********************************/

#include<iostream>
#include<stdlib.h>
#include<malloc.h>
#define MAX 100 /*最大顶点数为100*/
using namespace std;

typedef struct NODE{ /*边表结点*/
	int v_num;  /*邻接点域*/
	int len;    /*邻接顶点与下个邻接顶点的费用*/
	struct NODE * next; /*指向下个邻接顶点的指针*/
}EdgeNODE;

/*函数声明*/
void create_graph(EdgeNODE NODE[], int n, int e);
int fgraph(EdgeNODE NODE[], int cost[], int route[], int path[], int n);
void show_route(int route[]);

int main(){
	int n, e;   /*顶点数n,边数e*/
	cout << "请输入图的顶点数和边数:";
	cin >> n >> e; 

	EdgeNODE * NODE = new EdgeNODE[n]; //多段图邻接表头节点
	int * cost = new int[n];           //在阶段决策中,各个顶点到收点的最小费用
	int * route = new int[n];          //从源点到收点的最短路径上的顶点编号
	int * path = new int[n];
	/*在阶段决策中,各个顶点到收点的最短路径上的前方顶点编号*/

	create_graph(NODE, n, e);      //创建图的邻接表
	cout << endl<<"顶点到收点的最小花费为:";
	cout<<fgraph(NODE, cost, route, path, n); //输出最短路径费用

	cout <<endl<< "路径为:";
	show_route(route);  //输出最短路径

	system("pause");
	return 0;
}

/*创建图的邻接表*/
void create_graph(EdgeNODE NODE[], int n, int e){
	EdgeNODE * p;
	for (int k = 0; k< n; k++){
		NODE[k].v_num = k;
		NODE[k].len = 0;
		NODE[k].next = NULL;
	}
	
	cout <<endl<< "请输入"<<e<<"条边<i,j>和路径长度w:\n";
	int i, j, w; //i为边起点,j为边终点,w为边权值
	for (int t = 0; t < e; t++){
		cin >> i >> j >> w;  //输入边首尾点编号及其权值
		p = (EdgeNODE *)malloc(sizeof(EdgeNODE));
		p->v_num = j;
		p->len = w;
		p->next = NODE[i].next;
		NODE[i].next = p;
	}
}

/*求最短路径费用*/
int fgraph(EdgeNODE NODE[], int cost[], int route[], int path[], int n){
	EdgeNODE * pnode;

	// 初始化
	for (int i = 0; i < n; i++){   
		cost[i] = MAX;
		route[i] = 0;
		path[i] = -1;
	}
	cost[n - 1] = 0;

	for (int i = n - 2; i >= 0; i--){
		/*计算各个顶点到收点的最短费用,并确定各个顶点到收点的
		最小花费路径的前方顶点*/
		pnode = NODE[i].next;
		while (pnode != NULL){
			if (pnode->len + cost[pnode->v_num] < cost[i]){
				cost[i] = pnode->len + cost[pnode->v_num];
				path[i] = pnode->v_num;
			}
			pnode = pnode->next;
		}
	}

	/*从源点开始,递推的确定其前方顶点,直到收点为止*/
	int j = 0;  //源点为0
	while ((route[j] != n - 1) && (path[j] != -1)){
		j++;
		route[j] = path[route[j-1]];
	}
	return cost[0];
}

/*打印最短路径*/
void show_route(int route[]){
	cout << route[0];
	for (int i = 1; route[i] != NULL;i++)
		cout << "-->" << route[i];
	cout << endl;
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值