关于图中的Dijkstra算法(邻接矩阵版)

关于图中的Dijkstra算法(邻接矩阵版)

最近在学习图论,感觉也没有那么难…以前总觉得很难…


//
//  main.cpp
//  Dijkstra    ——不断从dis中选取最小的值,取这个节点(该节点未曾被访问),更新dis,再从dis中找最小值,如此反复
//  邻接矩阵版本
//  Created on 2020/10/25.
//

#include <iostream>
using namespace std ;
#include <stack>

const int INFINITY = 65535;//定义不可达
const int Max_Size = 100 ;
int n ,e ,starts ;//顶点个数,边数,初始点
int G[Max_Size][Max_Size];//图
int Visited[Max_Size];//标记是否到达过
int dist[Max_Size];//距离(相对初始点而言——starts)
int path[Max_Size];//路径,每次随距离一起更新

void Create(){//建立图
    cin >> n >> e >> starts;
    for(int i = 0 ;i<n ;i++ ){//初始化
        for(int j = 0 ;j<n ;j++){
            if(i == j ){
                G[i][j] = 0 ;
            }else {
                G[i][j] = INFINITY;
            }
        }
    }
    for(int i = 0 ;i<e ;i++ ){//插入边
        int v1, v2 ,w ;//w是权值
        cin >> v1 >> v2 >> w;
        G[v1][v2] = w ;
        G[v2][v1] = w ;
    }
}

void Dijkstra(){//每次对一个顶点操作更新
    fill(dist, dist+Max_Size, INFINITY);//将数组dis全部初始化为INFINITY(记为不可达)
    memset(Visited, 0, sizeof(Visited));
    dist[starts] = 0 ;//保证第一次找到的肯定是starts
    
    for(int i = 0 ;i<n;i++ ){//因为每次都是从未访问的节点中选取一个,然后有n个节点
        int u = -1 , min = INFINITY;
        for(int j = 0 ;j< n ;j++ ){
            if(Visited[j] == 0 && dist[j] < min){//在dis中,找最小的,同时保证未访问
                u = j ;
                min = dist[j] ;
            }
        }
        if(u == -1) return ;//未找到(表明starts点与其他点不连通)
        Visited[u] = 1 ;
        
        for(int j = 0 ;j<n;j++){//找到点之后,更新dis
            if(Visited[j] == 0 && G[u][j]!= INFINITY && dist[j] > dist[u] + G[u][j]){//原则:未访问,可达,距离更小
                dist[j] =dist[u] + G[u][j];
                path[j] = u;
            }
        }
    }
    cout <<"到各个顶点最短距离为:";
    for(int i = 0 ;i < n; i++){
        cout << dist[i]<< " " ;
    }
    cout << endl ;
}
void path_way(int i ){
    stack<int >s ;
    cout << "到达5的最短路径是:";
    s.push(i);
    
    while (i != 0){
        s.push(path[i]);
        i = path[i];
    }
    while(!s.empty()){
        cout << s.top()<< " ";
        s.pop();
    }
    cout << endl ;
}


int main() {
    Create();
    Dijkstra();
    
    path_way(5);
    return 0;
}

欢迎指出错误~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值