zoukankan      html  css  js  c++  java
  • 重学数据结构系列之——图论算法之Dijkstra算法

    学习来源:计蒜客

    1.Dijkstra算法定义

    迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。


    2.代码

    #include <iostream>
    #include <cstring>
    #include <vector>
    #include <queue>
    using namespace std;
    
    //定义一个较大的整形数
    const int INF = 0x3f3f3f3f;
    
    //边的定义,vertex:边的另外一个端点,weight:边的权值
    struct Edge {
    	int vertex, weight;
    };
    
    class Graph {
    private:
    	int n; //顶点个数
    	vector<Edge> * edges; //邻接表
    	bool * visited; //记录是否访问过了
    public:
    	int * dist; //这个用于保存从起点出发,到每个点的距离
    	Graph (int input_n) {
    		n = input_n;
    		edges = new vector<Edge>[n];
    		dist = new int[n];
    		visited = new bool[n];
    		memset(visited, 0, n);
    		memset(dist, 0x3f, n * sizeof(int));
    	}
    	~Graph() {
    		delete[] dist;
    		delete[] edges;
    		delete[] visited;
    	}
    	void insert(int x, int y, int weight) {
    		Edge edge1,edge2;  
    <span style="white-space:pre">		</span>edge1.vertex = x;  
    <span style="white-space:pre">		</span>edge1.weight = weight;  
    <span style="white-space:pre">		</span>edge2.vertex = y;  
    <span style="white-space:pre">		</span>edge2.weight = weight;  
    <span style="white-space:pre">		</span>edges[x].push_back(edge2);  
    <span style="white-space:pre">		</span>edges[y].push_back(edge1);
    	}
    	void dijkstra(int v) {
    		dist[v] = 0;
    		//外层循环是要找起点到n个顶点的最短路径
    		for (int i = 0; i < n; i++) {
    			int min_dist = INF, min_vertex;
    
    			//循环从未访问结点中,从起点出发,距离起点最近的点
    			//因为这里的dist是起点到每个顶点的距离
    			for (int j = 0; j < n; j++) {
    				//未访问且小于上一个记录最短距离(因为第一次循环后,除了起点旁边的顶点的dist被更新为权值,其他的还是大整数,以下图为例,这里i=1时,<span style="font-family: Arial, Helvetica, sans-serif;">min_vertex 应该是l</span>)
    				if (!visited[j] && dist[j] < min_dist) {
    					min_dist = dist[j];
    					min_vertex = j;
    				}
    			}
    			//标记为已访问
    			visited[min_vertex] = 1;
    			//其实就是更新当前min_vertex这个编号的点的周围结点的dist为最小的权值
    			for(Edge &j : edges[min_vertex]){ 
    				//当i=0时,就是第一次循环时,min_vertex就是下图的a点,下面就是更新a,e的距离为10,a,l的距离为5
    				//而当i=1,min_vertex是下图的l点,min_dist = 5, j第一个遍历到e,min_dist + j.weight = 5 + 3 = 8 < 10 = dist[j.vertex]
    				//所以更新起点a到e的最短距离
    				if (min_dist + j.weight < dist[j.vertex]) {
    					dist[j.vertex] = min_dist + j.weight;
    				}
    			}  
    
    		}
    	}
    };
    
    int main() {
    	int n, m;
    	cin >> n >> m;
    	Graph g(n);
    	for (int i = 0; i < m; i++) {
    		int a, b, c;
    		cin >> a >> b >> c;
    		g.insert(a, b, c);
    	}
    	//调用算法,起点到各点的最短路径都储存在数组中,下面将数组输出
    	g.dijkstra(0);
    	for (int i = 0; i < n; i++) {
    		cout << i << ": " << g.dist[i] << endl;
    	}
    	return 0;
    }



    环境:C++11
    运行结果:
    输入:

    输出:





  • 相关阅读:
    Redis命令总结
    jvisualvm远程监控Tomcat
    CentOS6安装glibc-2.14,错误安装libc.so.6丢失急救办法
    vsan分布式存储数据恢复全过程
    linux文件系统损坏修复方法,亲测可用
    案例讲解服务器硬盘离线数据恢复方法-数据恢复
    服务器数据丢失恢复过程
    数据恢复工程师讲述Linux服务器数据恢复过程
    了解这一点轻松解决Oracle数据库系统报错问题
    浅析RAID0/1安全差别及处理数据安全的应对方式
  • 原文地址:https://www.cnblogs.com/cnsec/p/13286540.html
Copyright © 2011-2022 走看看