【图】最短路径Dijkstra算法和Floyd算法

来源:互联网 发布:长城证券软件 编辑:程序博客网 时间:2024/06/01 09:53

一、Dijkstra算法

#include<iostream>using namespace std;const int maxint = 10000;class Dij{public:void initial(int m, int n);void read_case();void dijkstra(int begin, int end);void search_path(int begin, int end);// 查找从源点v到终点u的路径,并输出private:int path[101][101];// 图的两点间路径长度int distance[101];// 当前点到源点的最短路径长度int pre[101];// 记录当前点的前一个结点bool visited[101];int node_num;// 图的结点数int edge_num;// 图的路径数};void Dij::initial(int m, int n){node_num = m;edge_num = n;for (int i = 0; i < 101; i++){for (int j = 0; j < 101; j++){path[i][j] = maxint;}distance[i] = maxint;}memset(visited, false, sizeof(visited));}void Dij::read_case(){int n1, n2, len;for (int i = 1; i <= edge_num; i++){cin >> n1 >> n2 >> len;path[n1][n2] = path[n2][n1] = len;}}void Dij::dijkstra(int begin, int end){int i, j, k;for (i = 1; i <= node_num; i++){distance[i] = path[begin][i];if (distance[i] == maxint)pre[i] = 0;elsepre[i] = begin;}distance[begin] = 0;visited[begin] = true;for (i = 2; i <= node_num; i++){int min = maxint;// 找出当前未使用的点j的distance[j]最小值for (j = 1; j <= node_num; j++){if (distance[j] < min&&!visited[j]){k = j;min = distance[j];}}// 表示k点已被访问过 visited[k] = true;// 更新distance[j]for (j = 1; j <= node_num; j++){if (min + path[k][j] < distance[j] && !visited[j]){distance[j] = min + path[k][j];pre[j] = k;}}}cout << "源点到最后一个顶点的最短路径长度: " << distance[end] << endl;}// 查找从源点v到终点u的路径,并输出void Dij::search_path(int begin, int end){int que[101];int count = 1;que[count] = end;count++;int tmp = pre[end];while (tmp != begin){que[count] = tmp;count++;tmp = pre[tmp];}que[count] = begin;cout << "源点到最后一个顶点的路径为: ";for (int i = count; i >= 1; i--)if (i != 1)cout << que[i] << " -> ";elsecout << que[i] << endl;}int main(){int n, line;Dij x;int start, end;while (cin >> n >> line){x.initial(n, line);x.read_case();cin >> start >> end;x.dijkstra(start, end);x.search_path(start, end);}return 0;}
二、Floyd算法

#include<iostream>using namespace std;const int max_num = 500;//最大城市数const int max_len = 10000;//两城市间路径长度最大不超过10000class Street{public:    void init(int n, int m);    void read_case();    void floyd();    void search_path();private:    int city[max_num][max_num];//路径权重数组      int path[max_num][max_num];//保存最短路径数组,记录前继      int city_num;//城市数    int road_num;//城市间路径数    int start;    int end;};void Street::init(int n, int m){    city_num = n;    road_num = m;    for (int i = 0; i < max_num; i++){        for (int j = 0; j < max_num; j++){            if (i == j)                city[i][j] = 0;//注意自己对自己长度必须设为0            else                city[i][j] = max_len;            path[i][j] = j;        }    }}void Street::read_case(){    int c1, c2, len;    for (int i = 0; i < road_num; i++){        cin >> c1 >> c2 >> len;        city[c1][c2] = city[c2][c1] = len;    }    cin >> start >> end;}void Street::floyd(){    for (int k = 0; k < road_num; k++){        for (int i = 0; i < road_num; i++){            for (int j = 0; j < road_num; j++){                if (city[i][k] + city[k][j] < city[i][j]){                    city[i][j] = city[i][k] + city[k][j];                    path[i][j] = path[i][k];                }            }        }    }    cout << city[start][end] << endl;}void Street::search_path(){    int k = path[start][end];    cout << start;    while (k != end){        cout << " -> " << k;        k = path[k][end];    }    cout << " -> " << end << endl;}int main(){    int n, m;    Street s;    while (cin >> n >> m){        s.init(n, m);        s.read_case();        s.floyd();        s.search_path();    }    return 0;}

0 0