贪心-最短路径问题

问题描述:

给定若干城市以及各城市之间的路线,求出到达每个城市的最短路径。如下图所示,各字母代表城市,有边则代表城市之间连通,权值代表连通的城市之间的路径值。

图示:

在这里插入图片描述

Dijkstra求解:

1. Dijkstra思路分析

主要思想:通过构建的邻接矩阵,更新源点到所有顶点的路径。然后不断借助其他顶点更新源点到其他顶点的最短距离。
因此实现过程中,我们需要一个二维矩阵来保存各顶点间的连通关系。一个数组dist保存源点到达其他各顶点的距离。为了区别已经借助过的顶点和没有借助过的顶点,我们使用一个bool类型的数组保存各个顶点的使用关系。

2. 算法步骤
  1. 通过给定的各城市之间的连通关系,构建邻接矩阵(初始状态下,矩阵中各值为无穷大)
  2. 通过给定的源点,构建dist[]、p[]数组以及集合s和v-s(通过bool类型数组保存,若顶点在s中,则对应数组值赋为true)
  3. 在v-s中,寻找源点至其路径最短的顶点,并且将找到的顶点加入到s集合中
  4. 判断是否能借助上述找到的顶点,使到达其他顶点的路径最短
  5. 若存在这样的最短路径,则更新dist[]和p[]数组
  6. 直至v-s集合为空,表示已经找完了到达所有顶点的最短路径
代码示例:
#include<iostream>
using namespace std;

const int INT = 1e7;//定义无穷大 
const int N = 100;
int n, m, s;//定义城市个数/城市之间连线条数和源顶点
int map[N][N], dist[N], p[N];
bool flag[N];

void init_map(int map[N][N]){
 	for(int i = 0; i < N; i++){
  		for(int j = 0; j < N; j++)
   			map[i][j] = INT;
 	}
}
void dijkstra(int s){
 	for(int i = 1; i <= n; i++){//先初始化dist、p和集合s 
  		flag[i] = false;
  		dist[i] = map[s][i];
  		if(dist[i] != INT)
   			p[i] = s;
  		else 
   			p[i] = -1;
 	}
 	flag[s] = true;
 	dist[s] = 0;
 	int t = -1, min;//查找最短路径 
 	for(int i = 1; i <= n; i++){
  		min = INT;
  		for(int j = 1; j <= n; j++){
   			if(!flag[j] && dist[j] < min){//查找V-S中路径最小的顶点
    				min = dist[j];
   	 			t = j;
   			}
  		}
  		if(t == s) return;
  		flag[t] = true;
  		for(int j = 1; j <= n; j++){
   			if(!flag[j] && map[t][j] < INT){
    				if((dist[t] + map[t][j]) < dist[j]){
     					dist[j] = dist[t] + map[t][j];
     					p[j] = t;
    				} 
   			}
  		}
 	}
}

int main(){
 	init_map(map);
 	cin >> n >> m >> s;//城市个数/城市间连线条数/源顶点 
 	for(int i = 0; i < m; i++){//初始化邻接矩阵 
  		int x, y, z;
  		cin >> x >> y >> z;
  		map[x][y] = z;
 	}
 	dijkstra(s);
 	for(int i = 1; i <= n; i++){
  		cout << "最短路径为:" << dist[i] << endl;
 	}
 	return 0;
} 
结果输出:

在这里插入图片描述
参考文献:《趣味算法》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值