fsmly

每对结点之间的最短路径(Floyd-Warshall 算法)
补充 ALL-PATHS 算法,增加前驱矩阵(Chp.25.2),使得在求出结点间的最短路径长度矩阵
A 后,能够推导出每对结点间的最短路径。
1)测试文件:
  Input file:in.dat
    格式:第一行为一个整数,表示测试用例的组数,其后跟相应组数的测试用例,每组测试用例包括:首行:一个整数,表示本组测试用例包含的结点数 n,其后跟 n 行其后:每行 n 个整数,表示结点间邻接关系及边的长度(邻接成本矩阵边的长度<100,100 即表示结点间没有边。
  Output file:out.dat
    格式:第一行为一个整数,表示测试用例的组数,其后跟相应组数的测试用例每组测试用例输出包括:首行:一个整数,表示本组测试用例包含的结点数 n,其后跟 n+n 2 行其后:开始的 n 行,每行 n 个整数,表示结点间最短路径的长度(A 矩阵)。路径的程度<32767,32767 即表示结点间没有可达的路径。其后 n 2 行,顺次输出结点对(1,1)、(1,2)、…、(1,n),(2,1)、(2,2)、…、(2,n)、…(n,1)、…、(n,n)之间的最短路径结点序列,结点间用空格隔开。(i,i)输出 i,若(i,j)之间没有路径,输出 NULL。

2)代码实现

#include<iostream>
#include<string>
#include<fstream>
#include<sstream>
#include<vector>
using namespace std;
#define Max_Num 10
#define INF 32767

typedef struct Graph {
    //    int var[Max_Num];
    int edges[Max_Num][Max_Num];
    int n; //顶点数
}Graph;
vector<Graph> graph;
vector<int> num;
vector<string> res;
int count_num; //测试用例的组数
void newGraph();
void Floyd(Graph G, ofstream &fileWrite);
void DisPath(int A[][Max_Num], int path[][Max_Num], int n, ofstream &fileWrite);
void PrintPath(int path[][Max_Num], int i, int j, ofstream &fileWrite);
template <class Type>
Type stringToNum(const string& str) {
    istringstream iss(str);
    Type num;
    iss >> num;
    iss.str("");
    return num;
}

/*
 *从文件中将数据读出来
 */
void file_read() {
    string str2, str1 = "";
    int i = 0;
    ifstream fileRead("in.dat");
    if (fileRead.is_open()) {
        while (getline(fileRead, str2, '\n')) {
            if (i >= 1) {
                if (str2.find(" ") != -1) {
                    str1.append(str2 + " ");
                }
                else {
                    //num里面存放当前是多少维数组
                    num.push_back(stringToNum<int>(str2));
                    if (str1 != "") {
                        res.push_back(str1);
                    }
                    str1 = "";
                }
            } else if (i == 0) {
                count_num = stringToNum<int>(str2);
            }
            i++;
        }
        res.push_back(str1);
        fileRead.close();
    }
}

/*
 *将文件中的数据构建成图 然后放入vector中
 */
void newGraph() {
    string temp;
    Graph G;
    for (int i = 0; i < res.size(); i++) {
        vector<string> temp_str; //存放按照空格分开后的数字
        int n = num[i];
        stringstream input(res[i]);
        while (input >> temp) {
            temp_str.push_back(temp);
        }
        G.n = n;
        //将每一次读到的完成二维数组添加到Graph之中
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < n; k++) {
                int tem = stringToNum<int>(temp_str[j*n + k]);
                if (tem == 100) G.edges[j][k] = INF;
                else G.edges[j][k] = tem;
            }
        }
        graph.push_back(G);
    }
}

void Floyd(Graph G, ofstream &fileWrite) {
    int A[Max_Num][Max_Num], path[Max_Num][Max_Num];
    //初始化图表 和路径表
    for (int i = 0; i < G.n; i++) {
        for (int j = 0; j < G.n; j++) {
            A[i][j] = G.edges[i][j];
            path[i][j] = -1;
        }
    }
    //Floyd算法
    for (int k = 0; k < G.n; k++) {
        for (int i = 0; i < G.n; i++) {
            for (int j = 0; j < G.n; j++) {
                if (A[i][j] > (A[i][k] + A[k][j])) {
                    A[i][j] = A[i][k] + A[k][j];
                    path[i][j] = k;
                }
            }
        }
    }

    DisPath(A, path, G.n, fileWrite);
}

void DisPath(int A[][Max_Num], int path[][Max_Num], int n, ofstream &fileWrite) {
    //写入最短路径的距离
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (A[i][j] >= INF) {
                if (i != j) {
                    fileWrite<<"NULL"<<" ";
                }
            } else {
                fileWrite << A[i][j] <<" ";
            }
        }
        fileWrite << endl;
    }
    //写入最短路径所经过的结点
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            fileWrite << "(" << i+1 << "," << j+1 << ")=>" <<"(";
            if (A[i][j] >= INF) {
                if (i != j) {
                    fileWrite << "NULL)" << endl;
                }
                else if(i == j)fileWrite << i << " ";
            }
            else {
                fileWrite << i+1 << " ";
                PrintPath(path, i, j, fileWrite);
                fileWrite << j+1 << ")" <<endl;
            }
        }
    }
}
/*
 *递归打印路径信息
 */
void PrintPath(int path[][Max_Num], int i, int j, ofstream &fileWrite) {
    int k = path[i][j];
    if (k == -1) {
        return;
    }
    PrintPath(path, i, k, fileWrite); //从i到k
    fileWrite << k+1 << " ";
    PrintPath(path, k, j, fileWrite); //从k到j
}

int main() {
    file_read(); //将数据读入到文件中
    newGraph(); //将读入的数据添加到vector<Graph>中
    Graph G;
    ofstream fileWrite("out.dat");//打开要写入的文件
    fileWrite << count_num << endl;//写入测试的组数
    for (int i = 0; i < graph.size(); i++) {
        G = graph[i];
        fileWrite << G.n << endl;
        Floyd(G, fileWrite);
    }
    fileWrite.close();
    return 0;
}

相关文章:

  • 2021-11-30
  • 2021-08-28
  • 2021-10-16
  • 2019-09-24
猜你喜欢
  • 2021-08-01
  • 2021-08-30
  • 2021-08-12
  • 2021-09-21
  • 2021-08-15
  • 2021-08-30
相关资源
相似解决方案