有向图判环(leetcode207,leetcode210)

有向图判环(leetcode207,leetcode210)

有向图判环

#include <iostream>
#include <vector>
using namespace std;

struct graph {
    int V;                    // 顶点的数量
    vector<vector<int>> adj;  // 邻接表数组
    graph(int x): V(x), adj(x) {}
};

// 参数 graph 表示图,cur 表示当前顶点,vis 表示访问标记数组的引用,recStack 表示递归栈
bool dfs(graph &g, int cur, vector<bool> &vis, vector<bool> &recStack) {
    if (!vis[cur]) {
        vis[cur] = true;      // 标记当前顶点为已访问
        recStack[cur] = true; // 将当前顶点加入递归栈

        for (int nbr : g.adj[cur]) {
            if (!vis[nbr] && dfs(g, nbr, vis, recStack)) // 如果邻接顶点未被访问,则递归调用 dfs
                return true;
            else if (recStack[nbr])                      // 如果邻接顶点已经在递归栈中,则存在环
                return true;
        }
    }

    recStack[cur] = false;    // 从递归栈中移除当前顶点
    return false;
}

bool HasCycle(graph &g) {
    vector<bool> vis(g.V, false);      // 初始化访问标记数组,所有顶点均未被访问
    vector<bool> recStack(g.V, false); // 初始化递归栈

    for (int cur=0; cur<g.V; cur++) {
        if (!vis[cur] && dfs(g, cur, vis, recStack))
            return true; 
    }

    return false;
}

int main() {
    int V = 4;
    graph g(V);
    g.adj[0].push_back(1);
    g.adj[0].push_back(2);
    g.adj[1].push_back(2);
    g.adj[2].push_back(3);
    // g.adj[2].push_back(0);  // 有环:0->1->2->0
    // g.adj[3].push_back(3);  // 有环:3->3

    if (HasCycle(g))
        cout << "有环" << endl;
    else
        cout << "无环" << endl;

    return 0;
}

leetcode207

class Solution {
public:
    bool dfs(vector<vector<int>>& adj, int cur, vector<bool> &vis, vector<bool> &recStack) {
        if (!vis[cur]) {
            vis[cur] = true;      // 标记当前顶点为已访问
            recStack[cur] = true; // 将当前顶点加入递归栈

            for (int nbr : adj[cur])
                if (!vis[nbr] && dfs(adj, nbr, vis, recStack)) // 如果邻接节点未访问且有环,返回 true
                    return true;
                else if (recStack[nbr])                        // 如果邻接顶点已经在递归栈中,则存在环
                    return true;
        }

        recStack[cur] = false;    // 从递归栈中移除当前顶点
        return false;             // 没有检测到环
    }

    bool canFinish(int V, vector<vector<int>>& prerequisites) {
        vector<vector<int>> adj(V);      // 构建图的邻接表表示
        for (const auto& pre : prerequisites)
            adj[pre[1]].push_back(pre[0]);

        vector<bool> vis(V, false);      // 初始化访问标记数组,所有顶点均未被访问
        vector<bool> recStack(V, false); // 初始化递归栈

        for (int cur=0; cur <V; cur++)
            if (!vis[cur] && dfs(adj, cur, vis, recStack))
                return false; 

        return true;
    }
};

leetcode210

class Solution {
public:
    bool dfs(vector<vector<int>>& adj, int cur, vector<bool>& vis, vector<bool>& recStack, stack<int>& topOrder) {
        if (!vis[cur]) {
            vis[cur] = true;          // 标记为已访问
            recStack[cur] = true;     // 标记为在递归栈中

            for (int nbr : adj[cur])  // 遍历当前节点的邻接节点
                if (!vis[nbr] && dfs(adj, nbr, vis, recStack, topOrder))
                    return true;      // 如果邻接节点未访问且有环,返回 true
                else if (recStack[nbr])
                    return true;      // 如果邻接节点在递归栈中,说明有环
                
        }

        recStack[cur] = false; // 从递归栈中移除当前节点
        topOrder.push(cur);    // 将当前节点加入拓扑排序栈
        return false;          // 没有发现环
    }

    vector<int> findOrder(int V, vector<vector<int>>& prerequisites) {
        vector<vector<int>> adj(V);
        for (const auto& pre : prerequisites)  // 构建图的邻接表表示
            adj[pre[1]].push_back(pre[0]); 

        vector<bool> vis(V, false);            // 初始化访问标记数组,所有顶点均未被访问
        vector<bool> recStack(V, false);       // 初始化递归栈
        stack<int> topOrder;                   // 用于存储拓扑排序结果

        for (int cur = 0; cur < V; cur++)
            if (!vis[cur] && dfs(adj, cur, vis, recStack, topOrder))
                return {};                     // 如果发现环,返回空数组

        vector<int> result;
        while (!topOrder.empty()) {            // 将栈中的元素弹出,得到拓扑排序
            result.push_back(topOrder.top());
            topOrder.pop();
        }

        return result;
    }
};
上一篇:vertx idea快速使用


下一篇:【windows-bat脚本】-修改系统时间-解决方案: