最短路径问题(dijkstra算法)

11
0 11 27  11 12 29 26 42 22 36 34
11 0 18  3   4 19 16 32 13 28 25
27 18 0  18 16 9   6 17 15 11 13
11 3  18  0 3 19 16 32 15 27 25
12 4  16  3 0 17 15 31 14 26 24
29 19 9  19 17 0 7 17  20 11 17
26 16 6  16 15 7 0 17 14 14 12
42 32 17 32 31 17 17 0 25 13 11
22 13 15 15 14 20 14 25 0 26 15
36 28 11 27 26 11 14 13 26 0 18
34 25 13 25 24 17 12 11 15 18 0

直接给出问题的输入,第一行表示有多少个节点,接下来n行表示n个节点之间的距离,现要找出 从 某一 节点 到 其他节点的最短路径,两两节点可以都可以到达,但是每从 一个节点 到  另一个节点  时所经过的路程不能超过15。

关于dijkstra的思路,有其它博客讲的很清楚:https://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html

我的代码:

#include <iostream>
#include <cstring>
#include <iomanip>
#define INF 0x3f3f3f3f
using namespace std;

const int maxn = 1<<10; // 最大 2 的十次方

int n,map[maxn][maxn],way[maxn];       //n为节点个数

void djs(int start) {
	int dis[n+1], vis[n+1] = {0};
	memset(dis, 0x3f, sizeof(dis));
	dis[start] = 0; //自己到自己的距离为 0**************
	for(int i = 1; i <= n; i++) {        //循环n次  ==  迭代n次
		int flag = -1;
		for(int j = 1; j <= n; j++)                 //找到到 未访问的 start 最短的点
			if(vis[j] == 0) {
				if(flag == -1)  {
					flag = j;
					continue;
				} else if(dis[j] < dis[flag])	flag = j;
			}
		vis[flag] = 1;
		for(int j = 1; j <= n; j ++)                //更新dis
			if(dis[j] > dis[flag] + map[flag][j] && map[flag][j] <= 15)
				dis[j] = dis[flag] + map[flag][j],way[j] = flag; //记录到达某点最短距离的上一个节点 
	}
	for(int i = 1; i <= n; i++)
		cout <<setw(3) << setiosflags(ios::left) <<  dis[i] << "  ";
	cout <<endl;
}
void find(int start,int end) {
	int road[n], last = end;
	int flag=0;
	djs(start);
	while(1) {                  //返回去找 
		road[flag]=way[end];
		end=way[end];
		flag++;
		if(end==start)
			break;
	}
for(int i = flag - 1; i >= 0; i--)cout << road[i] << "=>";
cout << last;
}

int main() {
	memset(map, 0x3f, sizeof(map));
	cin >> n;            //初始化地图无穷大
	int temp;
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= n; j++)
			cin >> temp, map[i][j] = map[j][i] = temp;
	for(int i = 1; i <= n; i++) cout << setw(5) << setiosflags(ios::left) << i ;
	cout <<endl;
	for(int i = 1; i <= n; i++)	djs(i);
	cout << "你想知道从哪到哪的路径?";    //突然想知道最短路径是怎么走的,所以强行加上 
	int a, b; 
	cin >> a >> b;
	find(a, b); 
	return 0;
}
/* dijkstra
11
0 11 27  11 12 29 26 42 22 36 34
11 0 18  3   4 19 16 32 13 28 25
27 18 0  18 16 9   6 17 15 11 13
11 3  18  0 3 19 16 32 15 27 25
12 4  16  3 0 17 15 31 14 26 24
29 19 9  19 17 0 7 17  20 11 17
26 16 6  16 15 7 0 17 14 14 12
42 32 17 32 31 17 17 0 25 13 11
22 13 15 15 14 20 14 25 0 26 15
36 28 11 27 26 11 14 13 26 0 18
34 25 13 25 24 17 12 11 15 18 0
*/

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值