• Dijkstra算法学习总结


    1、用邻接矩阵实现(待填坑。。。)

    2、用邻接表实现

    邻接表定义

    1. #define MaxVertexnum 100 //最大顶点数量
    2. int dis[MaxVertexnum] = { 0 }; //单源最短路径
    3. bool vis[MaxVertexnum] = { 0 }; //访问标志位
    4. #define INF 0x7fffffff //最大值
    5. #define VertexType int //顶点类型
    6. #define InfoType int //边权重类型
    7. typedef struct ArcNode{
    8. int adjvex; //边指向结点
    9. InfoType info; //边权重
    10. struct ArcNode* next;
    11. };
    12. typedef struct VNode {
    13. VertexType name;
    14. ArcNode* first;
    15. }AdjList[MaxVertexnum];
    16. typedef struct {
    17. AdjList node;
    18. int vexnum;
    19. int arcnum;
    20. }ALGraph;

    具象理解,一共三种结构相互连接,可以类比树的孩子兄弟表示法以及散列表,三者有异曲同工之妙

     dijkstra实现

    1. 先在当前dis[]距离列表中找到未被访问且距离最小的点u
    2. 如果没有找到则代表所有点最短距离都已经计算完毕
    3. 若找到则取出u的所有邻接点,进行最短距离计算并更新
    4. 回到步骤(1)继续执行,直到运行完毕
    1. void dijkstra(ALGraph* G, int start) {
    2. fill(vis, vis + MaxVertexnum, 0); //访问标志初始化
    3. fill(dis, dis + MaxVertexnum, INF); //路径初始化
    4. dis[start] = 0; //源点到自己的距离为0
    5. int i, j, u, min;
    6. for (i = 0; i < G->vexnum; i++) {
    7. u = -1; //在未被访问过的顶点中找到距离最短的点
    8. min = INF;
    9. for (j = 1; j <= G->vexnum; j++) {
    10. if (vis[j] = false && dis[j] < min) {
    11. u = j;
    12. min = dis[j];
    13. }
    14. }
    15. if (u == -1) return; //所有顶点均已访问
    16. vis[u] = true;
    17. ArcNode* tmp = G->node[u].first; //找到距离最短的顶点u的邻接点
    18. printf("\n\n\n");
    19. while (tmp) {
    20. //若该邻接点未被访问过 且 源点到u的最短距离+u到该邻接点的距离小于该邻接点此前的最短距离
    21. if (vis[tmp->adjvex] == false && dis[u] + tmp->info < dis[tmp->adjvex])
    22. dis[tmp->adjvex] = dis[u] + tmp->info;
    23. tmp = tmp->next; //继续访问u的下一个邻接点
    24. }
    25. }
    26. }

     3、抽象实现Dijkstra算法模板(用于做题)

    1. #include
    2. using namespace std;
    3. struct node {
    4. int id, dis;
    5. bool friend operator < (const node& a, const node& b) {
    6. return a.dis > b.dis;
    7. }
    8. };
    9. int n, m, s;
    10. int ui, vi, wi;
    11. vectorint, int>> E[100];
    12. int dis[100];
    13. int vis[100];
    14. void dijkstra() {
    15. fill(dis, dis + 100, 1e9); //初始化dis列表
    16. dis[s] = 0;
    17. priority_queue Q;
    18. Q.push(node{ s, 0 });
    19. while (!Q.empty()) {
    20. int Now = Q.top().id; //当前Now顶点的距离最短
    21. int D = Q.top().dis; //D为Now顶点目前的最短距离
    22. Q.pop();
    23. //对应底下①语句,因每次更新数据都会把距离放进列表,故当计算完所有距离后依旧留下一堆无用数据,用此语句进行过滤
    24. if (vis[Now]) continue;
    25. vis[Now] = 1;
    26. for (auto it : E[Now]) { //访问Now的所有邻边
    27. int des = it.first;
    28. int weigh = it.second;
    29. if (dis[des] > D + weigh) { //源点到Now的距离+Now到des的距离 < 先前des的最短距离
    30. dis[des] = D + weigh;
    31. Q.push(node{ des, dis[des] }); //①
    32. }
    33. }
    34. }
    35. }
    36. int main() {
    37. cin >> n >> m >> s; //n:顶点数 m:边数,s:源点
    38. for (int i = 0; i < m; i++) {
    39. cin >> ui >> vi >> wi; //从ui到vi权重为wi的一条边
    40. E[ui].push_back({ vi,wi });
    41. }
    42. dijkstra();
    43. for (int i = 1; i <= n; i++) {
    44. printf("%d ", dis[i]);
    45. }
    46. return 0;
    47. }

     可由下图具象理解模板

     若要得到此图应如此输入数据,对比输入数据与上图右方抽象结构,你就可以发现内在联系

    1. 5 8 0
    2. 0 1 1
    3. 0 2 2
    4. 0 4 1
    5. 2 1 3
    6. 2 3 2
    7. 2 4 2
    8. 3 4 1
    9. 3 1 2

    输入输出样例

     输入 #1

    1. 4 6 1
    2. 1 2 2
    3. 2 3 2
    4. 2 4 1
    5. 1 3 5
    6. 3 4 3
    7. 1 4 4

    输出 #1

    0 2 4 3

  • 相关阅读:
    从应用访问Pod元数据-DownwardApi的应用
    JavaWeb后端
    悲观锁与乐观锁
    Windows 11 家庭中文版添加本地安全策略
    为华生物胆固醇甲氧基聚乙二醇CHOL-MPEG CLS-MPEG 新型胶束载体研究方向
    关于微信二次分享,自定义分享参数不生效问题
    深入理解Spring Boot Starter:概念、特点、场景、原理及自定义starter
    2023最新最热ChatGPT/GPT-4科研论文写作与项目开发及AI绘图实战
    Ventoy系统启动盘制作
    JavaScript中的四种枚举方式
  • 原文地址:https://blog.csdn.net/qq_21891843/article/details/126324602