Dijkstra最短路算法(单源最短路)

Dijkstra最短路算法(单源最短路)

过程详解:[最短路径问题]—Dijkstra 算法最详解 - zdr0的文章 - 知乎 https://zhuanlan.zhihu.com/p/129373740

下面是我的代码模板,因为是稠密图所以选择邻接矩阵

int n, m;
int g[N][N]; // 邻接矩阵
int dist[N]; // 当前点距离起点的最短距离
bool st[N]; 	 // 当前点的最短距离是否确定

int dijkstra() {

	memset(dist, 0x3f, sizeof dist); // 所有距离初始化成无穷大

	dist[1] = 0; // 第一个点确定

	for (int i = 0; i < n; ++i) {    // 循环n次 每个点都遍历一次
		
		int t = -1;

		for (int j = 1; j <= n; ++j) {
			// t表示当前点是否确定点
			// 如果t确定了还不是最小的点
			if (!st[j] && (t == -1 || dist[t] > dist[j])) {
				t = j;
			}
		}

		st[t] = true; // t确定将这个点标记

		for (int j = 1; j <= n; ++j) {
			dist[j] = min(dist[j], dist[t] + g[t][j]); // 将这个点之前的路线加起来
		}
		
	}

	if(dist[n] == 0x3f3f3f3f)
		return -1;
	else 
		return dist[n];
}

堆优化版:

这里是使用vector模拟的邻接表

#define MAXN 0x3f3f3f3f

typedef pair<int, int> PII;

const int N = 1e5 + 5;

// v表示从a点到b点中的b点 cost是从a到b的边的权重
struct Edge {
    int v, cost;
};

int n, m;
vector<Edge> g[N];
int dist[N]; // 所有点到起点的距离
bool st[N]; // 确定当前点是否是最小的点

// x到y的距离为z
void add(int x, int y, int z) {
    Edge tmp = {y, z};
    g[x].push_back(tmp);
}

int dijikstra(int start) {

    for(int i = 1; i <= n; ++i) dist[i] = MAXN;

    dist[start] = 0;

    priority_queue<PII, vector<PII>, greater<PII>> q;

    q.push({0, start}); // first存储距离 second存储节点编号

    while(!q.empty()) {
        auto t = q.top();
        q.pop();

        int num = t.second, distance = t.first;

        if(st[num]) continue;
        st[num] = true;

        for(int i = 0; i < g[num].size(); ++i) {
            int v =  g[num][i].v; // 当前所在的节点
            int cost = g[num][i].cost; // 从num到i的距离
            if(dist[v] > distance + cost) {
                dist[v] = distance + cost;
                q.push({dist[v], v});
            }

        }
    }

    if(dist[n] == MAXN)
        return -1;
    else 
        return dist[n];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值