Dijkstra算法 C++/Java

Dijkstra算法的核心就是把顶点集合分成两个,一个是记录已经知道距离的,另外一个剩下的,所以当知道距离的那个集合满了就代表最短路径已经找到。
不过复杂度挺高的【初学者还未清楚理解】
  1. 找到跟源点距离最近的点,更新其距离
  2. 然后将其放进已知集合,更新所有距离【松弛操作】
#include <iostream>
#include <cstdio>
#define MAXN 1000
#define MAXINF 299999999

using namespace std;

struct Grauph {
	int dist[MAXN + 10], pre[MAXN + 10];
	bool vis[MAXN + 10];
	int A[MAXN + 10][MAXN + 10];
};
Grauph G;
int n, m;
void init(Grauph &G, int n, int m) {
	for (int i = 0; i < n; i++) {
		G.dist[i] = MAXINF;
		G.vis[i] = 1;
		G.pre[i] = i;
		for (int j = 0; j <= n; j++) G.A[i][j] = MAXINF;
	}
}
void Dijkstra(Grauph &G, int s, int n) {
	G.dist[s] = 0;
	for (int i = 0; i < n; i++) {
		int k = 0;
		for (int j = 1; j <= n; j++)
			if (G.vis[j] && G.dist[j] < G.dist[k])k = j;
		G.vis[k] = 0;
		for(int j=1;j<=n;j++)
			if (G.vis[j] && G.dist[k] + G.A[k][j] < G.dist[j]) {
				G.dist[j] = G.dist[k] + G.A[k][j];
				G.pre[j] = k;
			}
	}
}
void dfs(int n) {
	if (G.pre[n] == n) {
		printf("%d", n);
		return;
	}
	dfs(G.pre[n]);
	printf(" -> %d", n);
	return;
}
int main(int argc, char** argv) {
	scanf("%d %d", &n, &m);
	init(G, n, m);
	for (int i = 0, x, y, w; i<m; ++i) {
		scanf("%d %d %d", &x, &y, &w);
		if (w<G.A[x][y]) {
			G.A[x][y] = w;
			G.A[y][x] = w;
		}
	}
	int s = 1;
	Dijkstra(G, s, n);
	printf("length(%d -> %d) : %d \n", s, n, G.dist[n]);
	dfs(n);
	return 0;
}

java实现

public class Dijkstra {
    private static int N = 1000;
    private static int[][] Graph = {
            {0, 1, 5, N, N, N, N, N, N},
            {1, 0, 3, 7, 5, N, N, N, N},
            {5, 3, 0, N, 1, 7, N, N, N},
            {N, 7, N, 0, 2, N, 3, N, N},
            {N, 5, 1, 2, 0, 3, 6, 9, N},
            {N, N, 7, N, 3, 0, N, 5, N},
            {N, N, N, 3, 6, N, 0, 2, 7},
            {N, N, N, N, 9, 5, 2, 0, 4},
            {N, N, N, N, N, N, 7, 4, 0}
    };

    public static void main(String[] args) {
        dijkstra(0, Graph);
    }

    public static void dijkstra(int vs, int[][] Graph) {
        int NUM = Graph[0].length;
        int[] prenode = new int[NUM];
        int[] mindist = new int[NUM];

        boolean[] find = new boolean[NUM];

        int vnear = 0;
        for (int i = 0; i < mindist.length; i++) {
            prenode[i] = i;
            mindist[i] = Graph[vs][i];
            find[i] = false;
        }
        find[vs] = true;
        for (int v = 1; v < Graph.length; v++) {
            int min = N;
            for (int j = 0; j < Graph.length; j++) {
                if (!find[j] && mindist[j] < min) {
                    min = mindist[j];
                    vnear = j;
                }
            }
            find[vnear] = true;
            for (int k = 0; k < Graph.length; k++) {
                if (!find[k] && (min + Graph[vnear][k]) < mindist[k]) {
                    prenode[k] = vnear;
                    mindist[k] = min + Graph[vnear][k];
                }
            }
        }
        for (int i = 0; i < NUM; i++) {
            System.out.println("v" + vs + "...v" + prenode[i] + "->v" + i + ",s=" + mindist[i]);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/sinat_40477296/article/details/83240019