【算法】【最短路】Dijkstra 迪杰斯特拉

一、原理

目的: 求某点到其它所有点的最短距离
三类集合: 确定了最短路的节点集合A、正在计算最短路的节点集合B、还未进行计算最短路节点的集合C。
大概流程:

  • 集合A为空,集合B只有初始节点
  • 从初始节点找到所有相邻节点,这些相邻节点加入集合B,初始节点加入A。
  • 从集合B中找到距离初始节点最近的节点,从集合A之外的节点中找这个节点所有相邻节点,相邻节点加入集合B,该节点加入集合A
  • 循环上一步直至所有节点加入集合A

二、应用与例题

力扣743 单源最短路,求最短路中的最大值

public class Dijkstra743 {


    private final static int INF = 0x3f3f3f3f;
    int[] dis;
    int[] vis;
    int[][] cost;

    private void dijkstra(int n) {
        while (true) {
            int next = -1;
            for (int i = 1; i <= n; i++) {
                if (vis[i] == 0 && (next == -1 || dis[next] > dis[i])) {
                    next = i;
                }
            }
            if (next == -1) {
                break;
            }
            vis[next] = 1;
            for (int i = 1; i <= n; i++) {
                if (vis[i] == 0) {
                    dis[i] = Math.min(dis[i], dis[next] + cost[next][i]);
                }

            }
        }
    }

    private int calculate() {
        int res = 0;
        for (int i = 1; i < dis.length; i++) {
            if (dis[i] == INF) {
                return -1;
            }
            res = Math.max(res, dis[i]);
        }
        return res;
    }

    private void init(int[][] times, int n, int k) {
        dis = new int[n + 1];
        vis = new int[n + 1];
        Arrays.fill(dis, INF);
        dis[k] = 0;
        cost = new int[n + 1][n + 1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                cost[i][j] = INF;
                if (i == j) {
                    cost[i][j] = 0;
                }
            }
        }
        for (int[] time : times) {
            cost[time[0]][time[1]] = time[2];
        }
    }

    public int networkDelayTime(int[][] times, int n, int k) {
        init(times, n, k);
        dijkstra(n);
        return calculate();
    }

    public static void main(String[] args) {
        Dijkstra743 bellmanFord743 = new Dijkstra743();
        System.out.println(bellmanFord743.networkDelayTime(new int[][]{{2, 1, 1}, {2, 3, 1}, {3, 4, 1}}, 4, 2));
    }
}

POJ - 1847Tram dijkstra
Tram network in Zagreb consists of a number of intersections and rails connecting some of them. In every intersection there is a switch pointing to the one of the rails going out of the intersection. When the tram enters the intersection it can leave only in the direction the switch is pointing. If the driver wants to go some other way, he/she has to manually change the switch.
建图,点与相连的第一个点边值为0,与其他点相连为1,与不相连点的边为INF。
用dijkstra直接求。

#include<queue>
#include<stdio.h>
#include<string>
#include<iostream>
#include<map>
#include<limits>
#include<math.h>

using namespace std;
#define N 1000
#define LL long long int
#define pow(a) ((a)*(a))
#define INF 0x3f3f3f3f
#define mem(arr,a) memset(arr,a,sizeof(arr))
int n, a, b;
int cost[N][N];
int vis[N];
int d[N];
void dijkstra(){
	mem(d, INF);
	mem(vis, 0);
	d[a] = 0;
	int cnt = 0;
	while (1){
		cnt++;
		int v = -1;
		for (int i = 1; i <= n; i++){
			if (!vis[i] && (v == -1 || d[i] < d[v]))v = i;
		}
		if (v == -1)break;
		vis[v] = 1;
		for (int i = 1; i <= n; i++){
			if (d[i]>d[v] + cost[v][i]){
				d[i] = d[v] + cost[v][i];
			}
		}
		
	}
	if (d[b]!=INF)
	cout << d[b] << endl;
	else cout << -1 << endl;
}
int main(){
	cin >> n >> a >> b;
	mem(cost, INF);
	for (int i = 1; i <= n; i++){
		int t; cin >> t;
		int to; cin >> to;
		cost[i][to] = 0;
		for (int j = 1; j < t; j++){
			cin >> to;
			cost[i][to] = 1;
		}
	}
	dijkstra();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值