设计可以求最短路径的图类

类包括根据顶点数和边初始化的构造函数,添加边,求两点最短路径等函数

1. 迪杰斯特拉算法(邻接矩阵)

class Graph {
private:
    vector<vector<int>> graph;
public:
    Graph(int n, vector<vector<int>>& edges) {
        graph.resize(n,vector<int>(n,INT_MAX/2));
        for(auto&edge:edges){
            int from = edge[0];
            int to = edge[1];
            graph[from][to] = edge[2];
        }
    }
    
    void addEdge(vector<int> edge) {
        int from = edge[0];
        int to = edge[1];
        graph[from][to] = edge[2];
    }
    
    int shortestPath(int node1, int node2) {
        int n = graph.size();
        vector<bool> vis(n);
        vector<int> dis(n,INT_MAX/2);
        dis[node1] = 0;
        for(int times=0;times<n;times++){//最多遍历n次
            int cur = -1;
            for(int i=0;i<n;i++){//贪心找最小值
                if(vis[i]||dis[i]==INT_MAX/2) continue;//跳过已经选取的点和无法到达的点
                if(cur==-1||dis[i]<dis[cur]) cur = i;
            }
            if(cur==-1) return -1;//表示无法到达目标
            if(cur==node2) break; //找到目标直接跳出,此时dis[cur]即为最短路径,无需再更新
            vis[cur] = 1;
            //找到当前最近点后,根据最近点进行更新
            for(int i=0;i<n;i++){
                if(vis[i]||graph[cur][i]==INT_MAX/2) continue;//对应点已选取,或对应的边不存在,无需更新
                dis[i] = min(dis[i],dis[cur]+graph[cur][i]);
            }
        }
        return dis[node2]==INT_MAX/2?-1:dis[node2];
    }
};

2. Floyd算法

class Graph {
private:
    vector<vector<int>> graph;
public:
    Graph(int n, vector<vector<int>> &edges) {
        // 邻接矩阵(初始化为无穷大,表示 i 到 j 没有边)
        graph.resize(n, vector<int>(n,INT_MAX/3));
        for (int i = 0; i < n; ++i)
            graph[i][i] = 0; //自己到自己距离为0
        for (auto &edge: edges)
            graph[edge[0]][edge[1]] = edge[2];//初始化各点之间的距离
        for (int k = 0; k < n; ++k) //借助中间节点k
            for (int i = 0; i < n; ++i) //更新i节点
                for (int j = 0; j < n; ++j) //与j节点的距离
                    graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j]);
    }

    void addEdge(vector<int> edge) {
        int x = edge[0], y = edge[1], weight = edge[2], n = graph.size();
        if (weight >= graph[x][y]) // 加入边的权值大于两点间的距离,该边对更新没有作用
            return;
        graph[x][y] = weight;
        //借助该节点更新所有节点间的距离
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < n; ++j)
                graph[i][j] = min(graph[i][j], graph[i][x] + graph[x][y] + graph[y][j]);
    }

    int shortestPath(int start, int end) {
        int res = graph[start][end];
        return res==INT_MAX/3?-1:res;
    }
};
posted @ 2023-05-27 13:46  失控D大白兔  阅读(8)  评论(0编辑  收藏  举报