最短路径 Dijkstra算法 HDOJ_2544

来源:互联网 发布:淘宝能发布多少个宝贝 编辑:程序博客网 时间:2024/06/07 08:27

本文提纲

  1. 算法简介
  2. 算法思想
  3. 代码实现
  4. 反思与感悟

1.算法简介

Dijkstra算法,用于计算正权图上的单源最短路,即从单个源点出发,到所有结点的最短路。该算法适用于有向图和无向图,不能处理带有负权的图。

2. 算法思想

思想为单源点加入集合,更新dis[]数组,每次取dis[]最小的那个点,加入集合,再次更新dis[]数组,取点加入集合,直到所有的点都加入集合中

3.代码实现

以杭电2544题为例:

#include <stdio.h>#include <string.h>#define M 105#define INF 0x3f3f3f3fint map[M][M], low[M], n, m;bool vis[M];int dijstra(){    int ans = 0, pos, min, i, j;    //初始化数据    for(i = 2; i <= n; i ++){        //把和起点相连的顶点都加上权值        low[i] = map[1][i];        //标记都为0,表示都没有求到最短路径        vis[i] = 0;    }    //表示起点不用最短路径    vis[1] = 1;    low[1] = 0;    pos = 1;    //主循环,每次循环求得起点与一个顶点的最短路径    for(i = 2; i < n; i ++){        min = INF;        //找到一条最短路径        for(j = 2; j <= n; j ++){            if(!vis[j]&&low[j]<min){                min = low[j];                pos = j;            }        }        //        ans += min;        //将这个已经找到最短路径的节点标记为已遍历        vis[pos] = 1;        //通过已遍历的这个节点找到下一层节点,并更新low数组的值,相当于一次松弛操作        for(j = 2; j <= n; j ++){            if(!vis[j]&&low[j] > low[pos]+map[pos][j])                low[j] = low[pos]+map[pos][j];        }    }    return low[n];}int main(){//    freopen("test.txt","r",stdin);//    freopen("test.txt","w",stdout);    while(scanf("%d%d", &n, &m), n||m){        int i, j, a, b, c;        for(i = 0; i <= n; i ++){            for(j = 0; j <= n; j ++)                map[i][j] = INF;        }        for(i = 0; i < m; i ++){            scanf("%d%d%d", &a, &b, &c);            if(map[a][b] > c){                map[a][b] = map[b][a] = c;            }        }        printf("%d\n", dijstra());    }//    fclose(stdin);//关闭文件//    fclose(stdout);//关闭文件    return 0;}

4.思想感悟

本次实现的Dijkstra算法还不是最优的,可以有队列进行优化,达到ElogV复杂度的最优算法。

0 0