floyd(弗洛伊德)算法,用于计算最短路径

程序小白,希望和大家多交流,共同学习

//弗洛伊德(floyd)算法,用于计算最短路径
#include<iostream>
#include<string>
#include<iostream>
#include<iomanip>
#define MAX_VN 50
#define INF 32767
using namespace std;
typedef string VertexData;
struct AdjMatrix{
    VertexData vertex[MAX_VN];
    int arcs[MAX_VN][MAX_VN];
    int verNum, arcNum;
};

void createAdjMatrix(AdjMatrix &G);
int locateVertex(AdjMatrix &G, VertexData data);
void outputAdjMatrix(AdjMatrix &G);

//Floyd
void floyd(const AdjMatrix &G);
string getVertex(const AdjMatrix &G, int i);

int main(){
/*
6 10
v1 v2 v3 v4 v5 v6
v1 v2 5
v1 v4 7
v2 v3 4
v3 v1 8
v3 v6 9
v4 v3 5
v4 v6 6
v5 v4 5
v6 v1 2
v6 v5 1
*/
    AdjMatrix G;
    createAdjMatrix(G);
    outputAdjMatrix(G);
    floyd(G);
    return 0;
}

void createAdjMatrix(AdjMatrix &G){
    cout << "输入顶点数和弧的条数:";
    cin >> G.verNum >> G.arcNum;
    cout << "输入顶点信息:";
    for (int i = 0; i < G.verNum; i++){
        cin >> G.vertex[i];
    }
    for (int i = 0; i < G.verNum; i++){
        for (int j = 0; j < G.verNum; j++){
            G.arcs[i][j] = INF;
        }
    }
    cout << "输入弧的信息:";
    VertexData u, v;
    int w, j, k;
    for (int i = 0; i < G.arcNum; i++){
        cin >> u >> v >> w;
        j = locateVertex(G, u);
        k = locateVertex(G, v);
        G.arcs[j][k] = w;
    }
}
int locateVertex(AdjMatrix &G, VertexData data){
    for (int i = 0; i < G.verNum; i++){
        if (G.vertex[i] == data){
            return i;
        }
    }
    return -1;
}
void outputAdjMatrix(AdjMatrix &G){
    for (int i = 0; i < G.verNum; i++){
        for (int j = 0; j < G.verNum; j++){
            if (G.arcs[i][j] != INF){
                printf("%-3d", G.arcs[i][j]);
            }
            else
                cout << "∞ ";
        }
        cout << endl;
    }
}

void floyd(const AdjMatrix &G){
    int n = G.verNum;
    int dist[n][n];//用来记录到达各个顶点的最短路径
    string path[n][n];//用来记录最短路径的路线

    for (int i = 0; i < n; i++){//初始化路线和最短路径值
        for (int j = 0; j < n; j++){
            dist[i][j] = G.arcs[i][j];
            //顶点到达自己 是没有意义的
            if (i == j){
                dist[i][j] = 0;
            }
            path[i][j] = "";//初始化为不可达
            if (dist[i][j] != 0){
                path[i][j] = getVertex(G, i) + getVertex(G, j);
            }
        }
    }
    //按照AdjMatrix的信息更新dist和path
    //更新:将第k行逐个扫描,每扫描一个就紧接着扫描它的邻接点
    //当邻接点的权值回和原点的权值和小于dist中的值就更新dist同时更新path
    //达到的目的就是使可达点的路径值最小,同时记录这条路径
    for (int k = 0; k < n; k++){
        for (int i = 0; i < n; i++){
            for (int j = 0; j < n; j++){
                if (i != j && dist[i][j] > dist[i][k] + dist[k][j]){
                    dist[i][j] = dist[i][k] + dist[k][j];
                    string sub = getVertex(G, k);
                    int index = path[i][k].find(sub);
                    path[i][j] = path[i][k].substr(0, index) + path[k][j];
                }
            }
        }
    }

    //输出路径值和路线
    cout << "D  |";
    for (int i = 0; i < n; i++){
        cout << setw(9) << i;
    }
    cout << endl;
    for (int i = 0; i < n; i++){
        cout << "---------";
    }
    cout <<endl;
    for (int i = 0; i < n; i++){
        cout << i << "  |";
        for (int j = 0; j < n; j++){
            cout << setw(9) << dist[i][j];
        }
        cout << endl;
    }
    cout << endl;

    cout << "P  |";
    for (int i = 0; i < n; i++){
        cout << setw(9) << i;
    }
    cout << endl;
    for (int i = 0; i < n; i++){
        cout << "---------";
    }
    cout << endl;
    for (int i = 0; i < n; i++){
        cout << i << "  |";
        for (int j = 0; j < n; j++){
            cout << setw(9) << path[i][j];
        }
        cout << endl;
    }
    cout << endl;

}
string getVertex(const AdjMatrix &G, int i){
    if (i >= 0 && i < G.verNum){
        return G.vertex[i];
    }
}

猜你喜欢

转载自blog.csdn.net/cheng_cuo_tuo/article/details/80578291