Dijkstra求最短路径

把m1.txt与可执行文件放在统一路径下

m1.txt(距离矩阵,9行9列)的数据如下:

9999    6   3   1   9999    9999    9999    9999    9999    
9999    9999    9999    9999    1   9999    9999    9999    9999    
9999    2   9999    2   9999    9999    9999    9999    9999    
9999    9999    9999    9999    9999    10  9999    9999    9999    
9999    9999    9999    6   9999    4   3   6   9999    
9999    9999    9999    9999    10  9999    2   9999    9999    
9999    9999    9999    9999    9999    9999    9999    4   9999    
9999    9999    9999    9999    9999    9999    9999    9999    9999    
9999    9999    9999    9999    2   9999    9999    3   9999

程序如下:

#include <iostream>
#include <fstream>

using namespace std;

#define MAX_NODE 100
#define MAX_INT 9999

int n1, n2; // 分别表示矩阵的行和列


int main(int argc, char* argv[]){

    int** readTxtToArrayWithoutKnowRowOrColumn(const char* strPath);

    void printArray(int **a, int m, int n);

    int** m = 0;
    int p[MAX_NODE] = {0}; // 记录当前路径长度
    int pt[MAX_NODE] = {0}; // 记录当前路径是否是最短路径,1表示是

    for(int i = 1; i < MAX_NODE; i++){
        p[i] = MAX_INT;
    }

    cout << "read data" << endl;

    m = readTxtToArrayWithoutKnowRowOrColumn("m1.txt");     

    cout << "行数: " << n1 << ", 列数: " << n2 << endl;

    printArray(m, n1, n2);

    cout << "用Dijkstra算法求最短路径:" << endl;

    p[0] = 0; // v1到v1的路径为0
    pt[0] = 1; // 当前v1到v1的路径是最短路径

    for(int i = 0; i < n1 - 1; i++){ // 求n个节点中1个节点到另一个节点的最短路径最多需要n-1步
        for(int j = 1; j < n1; j++){
            if(pt[j] != 1){
                // 还没有求出第1个节点到第j个节点的最短路径
                for(int k = 0; k < n1; k++){
                    // 计算第1个节点到第j个节点的路径
                    if(pt[k] == 1){
                        // k是已经求出最短路径的节点
                        if(m[k][j] < MAX_INT){
                            // 如果k到j有路径
                            if((p[k] + m[k][j]) < p[j]){
                                p[j] = p[k] + m[k][j];
                            }   
                        }
                    }

                }
            }
        }

        int tmp = MAX_INT;
        for(int j = 1; j < n1; j++){
            if(pt[j] != 1){
                if(p[j] < tmp){
                    tmp = p[j];
                }
            }
        }

        for(int j = 1; j < n1; j++){
            if(pt[j] != 1){
                if(p[j] == tmp){
                    pt[j] = 1;
                }
            }
        }
    }


    cout << "第1个节点到其他各个节点的最短路径如下:" << endl;
    for(int i = 0; i < n1; i++){
        cout << p[i] << "\t";
    }
    cout << endl;

    return 0;
}


int** readTxtToArrayWithoutKnowRowOrColumn(const char* strPath){
    int** a = new int* [MAX_NODE];
    for(int i = 0; i < MAX_NODE; i++){
        a[i] = new int[MAX_NODE];
    }
    int nTmp = 0;
    n1 = 0;
    n2 = 0;
    ifstream is(strPath);
    if(!is){
        cout << "open file error!" << endl;
    }else{
        char p;
        int num;
        int j = 0;
        while(is.get(p)){ // 判断是否到达文末
            do{
                if(p == '\n'){
                     n1++; // 统计行数
                     if(n2 == 0){
                         n2 = nTmp; // 实际上只统计了第一行的列数
                     }
                     j = 0;
                     // cout << endl; // 一行之后输出一个回车符
                }
            }while(isspace((int)p) && is.get(p));
            if(!is)
                break;
            nTmp++; // 统计列数
            is.putback(p); // 如果前面读入的不是空格或者回车符,则把刚才读入的字符返回文件流
            is >> num;
            // cout << num << "\t";
            a[n1][j++] = num;
        }     
    }
    is.close();
    return a;
}

void printArray(int** a, int m, int n){
  for(int i = 0; i < m; i++){
    for(int j = 0; j < n; j++){
      cout << a[i][j] << "\t";
    }
    cout << endl;
  }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值