ZBLOG

class DirectedGraph { private: int numVertices; vector adjacencyList; public: DirectedGraph(int n) : numVertices(n), adjacencyList(n) {} void addEdge(int u, int v, int weight) { adjacencyList[u].pu...

注释如下:

class DirectedGraph {
private:
    int numVertices; // 图中顶点的数量
    vector<vector<pair<int, int>>> adjacencyList; // 邻接表,存储每个顶点的出边和对应的权重

public:
    DirectedGraph(int n) : numVertices(n), adjacencyList(n) {} // 构造函数,初始化图的顶点数量和邻接表大小

    void addEdge(int u, int v, int weight) {
        adjacencyList[u].push_back(make_pair(v, weight)); // 添加一条从顶点u到顶点v的有向边,并设置权重为weight
    }

    vector<int> topologicalSort() {
        vector<int> inDegree(numVertices, 0); // 记录每个顶点的入度

        for (int u = 0; u < numVertices; ++u) { // 遍历所有顶点
            for (auto& edge : adjacencyList[u]) { // 遍历当前顶点u的出边
                int v = edge.first; // 出边连接的顶点v
                ++inDegree[v]; // 递增顶点v的入度
            }
        }

        queue<int> q;
        for (int u = 0; u < numVertices; ++u) {
            if (inDegree[u] == 0) { // 将入度为0的顶点入队列
                q.push(u);
            }
        }

        vector<int> sortedOrder;

        while (!q.empty()) {
            int u = q.front(); 
            q.pop();

            sortedOrder.push_back(u); // 将当前顶点加入排序结果

            for (auto& edge : adjacencyList[u]) { // 遍历当前顶点的出边
                int v = edge.first; // 出边连接的顶点v
                --inDegree[v]; // 递减顶点v的入度

                if (inDegree[v] == 0) { // 如果顶点v的入度变为0,将其入队列
                    q.push(v);
                }
            }
        }

        return sortedOrder; // 返回拓扑排序结果
    }

    void findCriticalPath() {
        vector<int> inDegree(numVertices, 0); // 记录每个顶点的入度

        for (int u = 0; u < numVertices; ++u) { // 遍历所有顶点
            for (auto& edge : adjacencyList[u]) { // 遍历当前顶点u的出边
                int v = edge.first; // 出边连接的顶点v
                ++inDegree[v]; // 递增顶点v的入度
            }
        }

        vector<int> startTime(numVertices, 0); 
        vector<int> endTime(numVertices, 0);

        queue<int> q;

        for (int u = 0; u < numVertices; ++u) {
            if (inDegree[u] == 0) { // 将入度为0的顶点入队列
                q.push(u);
            }
        }

        while (!q.empty()) {
            int u = q.front();
            q.pop();

            for (auto& edge : adjacencyList[u]) { // 遍历当前顶点的出边
                int v = edge.first; // 出边连接的顶点v
                int weight = edge.second; // 边的权重

                inDegree[v]--;

                startTime[v] = max(startTime[v], startTime[u] + weight); // 计算顶点v的开始时间

                if (inDegree[v] == 0) { // 如果顶点v的入度变为0,将其入队列
                    q.push(v);
                }
            }

            endTime[u] = startTime[u]; // 设置当前顶点u的结束时间等于开始时间(只有一个路径)
        }

        int criticalPathLength = *max_element(endTime.begin(), endTime.end()); // 找到关键路径长度

        cout << "Critical path length: " << criticalPathLength << endl;

        cout << "Critical path nodes: ";

        int currentNode = -1;

        for (int i = 0; i < numVertices; ++i) {
            if (endTime[i] == criticalPathLength && currentNode == -1) {
                currentNode = i;
                cout << currentNode << " "; // 输出关键路径上的第一个节点
            }
            else if (endTime[i] == criticalPathLength && startTime[i] == startTime[currentNode]) {
                currentNode = i;
                cout << currentNode << " "; // 输出和第一个节点具有相同开始时间的其他节点
            }
        }

        cout << endl;
    }


};

以上是一个使用邻接表实现有向图的C++类,包含了添加边、拓扑排序和寻找关键路径等功能。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=16068

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?