DS图应用--最短路径(附思路解析)

题目描述
给出一个图的邻接矩阵,再给出指定顶点v0,求顶点v0到其他顶点的最短路径

代码框架如下:

输入
第一行输入t,表示有t个测试实例

第二行输入n,表示第1个图有n个结点

第三行起,每行输入邻接矩阵的一行,以此类推输入n行

第i个结点与其他结点如果相连则为1,无连接则为0,数据之间用空格隔开

第四行输入v0,表示求v0到其他顶点的最短路径距离

以此类推输入下一个示例

输出
每行输出v0到某个顶点的最短距离和最短路径

每行格式:v0编号-其他顶点编号----[最短路径],具体请参考示范数据

样例输入
1
5
0 5 0 7 15
0 0 5 0 0
0 0 0 0 1
0 0 2 0 0
0 0 0 0 0
0
样例输出
0-1-5----[0 1 ]
0-2-9----[0 3 2 ]
0-3-7----[0 3 ]
0-4-10----[0 3 2 4

推荐思路:

在这里插入图片描述
视频链接:https://www.bilibili.com/video/BV1rz411v7f2?from=articleDetail

#include<iostream>
#include<stack>
using namespace std;

const int MaxLen = 20;
const int MaxDist = 9999;

class Map {
	private:
		int map[MaxLen][MaxLen];
		int Vexnum;
	public:
		void SetMatrix(int vnum, int mx[MaxLen][MaxLen]) {
			Vexnum = vnum;
			for(int i = 0; i < Vexnum; i++) {
				for(int j = 0; j < Vexnum; j++) {
					map[i][j] = MaxDist;
				}
			}
			for(int i = 0; i < Vexnum; i++) {
				for(int j = 0; j < Vexnum; j++) {
					if(mx[i][j])
						map[i][j] = mx[i][j];
				}
			}
		}
		int findMinDist(int *dist,bool *final) {
			int min = 9999,k;
			for(int i = 0; i <Vexnum; i++) {
				if(!final[i] && dist[i] < min){
					min = dist[i];
					k = i;
					}
				}
			return k;
		}
		void displayPath(int v0,int *path,int *dist){
			for(int i = 0; i < Vexnum; i++){
				if(i == v0){
					i++;
					if(i == Vexnum)
						return;
				}									
				cout<<v0<<"-"<<i<<"-"<<dist[i]<<"----["<<v0<<" ";
				stack<int> s;
				int j = i;
				while(path[j] != v0){
					s.push(path[j]);
					j = path[j];
				}
				while(!s.empty()){
					cout<<s.top()<<" ";
					s.pop();
				}
				cout<<i<<" ]\n";
			} 
		
		} 
		void ShortestPath_DIJ(int v0) {
			int i, j , v , w, min;
			int *dist = new int[Vexnum];
			bool *final = new bool[Vexnum];
			int *path = new int[Vexnum];

			for(i = 0; i < Vexnum; i++) {
				dist[i] = map[v0][i];
				final[i] = 0;
				if(dist[i] != 9999) {
					path[i] = v0;
				} else {
					path[i] = -1;
				}
			}
			final[v0] = 1;
			int num = 1;
			while(num < Vexnum) {
				min = findMinDist(dist,final);
				final[min] = 1;
				for(i = 0; i < Vexnum; i++) {
					if((!final[i]) && (dist[min] + map[min][i] < dist[i])) {
						dist[i] = dist[min] + map[min][i];
						path[i] = min;
					}

				}
				num++;
			}
			displayPath(v0,path,dist);
			delete []path;
			delete []final;
			delete []dist;
		}
};

int main() {
	int i,j,k,t;
	int vnum,v0;
	int mx[MaxLen][MaxLen];
	Map myMap;
	cin>>t;
	for(int k = 0; k < t; k++) {
		for(i = 0; i < MaxLen; i++) {
			for(j = 0; j < MaxLen; j++) {
				mx[i][j] =0;
			}
		}
		cin>>vnum;
		for(i = 0 ; i < vnum; i++) {
			for(j = 0; j < vnum; j++) {
				cin>>mx[i][j];
			}
		}
		myMap.SetMatrix(vnum,mx);
		cin>>v0;
		myMap.ShortestPath_DIJ(v0);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值