一二三四五 上山打老虎

Leetcode每日一题-2021-8-5<找到最终的安全状态>(判环)

链接:https://leetcode-cn.com/problems/find-eventual-safe-states/

题意:如果在环上或者能到达再环上的点则不满足题意,否则输出。

方法一:DFS+染色 判环:
0:未访问过
1:在环上或者在递归的过程中
2:不在环上也不到环

代码:

class Solution {
public:
    vector<int> eventualSafeNodes(vector<vector<int>>& g) {
        vector<int>f(g.size(),0);

        function<bool(int)> cou=[&](int x){
            if(f[x]>0)return f[x]==2;
            f[x]=1;
            for(int i=0;i<g[x].size();i++){
                if(!cou(g[x][i])){
                    return false;
                }
            }
            f[x]=2;
            return true;
        };
        vector<int> ans;
        for(int i=0;i<g.size();i++){
            if(cou(i))ans.emplace_back(i);
        }
        return ans;
    }
};

方法2:拓扑排序判环
思路不容易想:
平时我们可以通过能够拓扑遍历完整个图来判断图是否是无环图,在本题中我们需要判断的是每个点是否在环中或者能够到达环。
分析原先我们直接对图进行拓扑排序会发现,我们先去掉入度为0的点,再去对此点所连的点去分析,而在本题中我们需要根据所连的点去分析此点是否满足条件,据此我们需要将图中所有边的方向反转,将原来拓扑排序所求的入度对此点影响转化为原先的出度对此点的影响,反转图后,当此点的入度为0,则代表原图中此点所到达的点与环无关。

代码:

class Solution {
public:
    unordered_map<int,vector<int>> m;
    vector<int> eventualSafeNodes(vector<vector<int>>& g) {
        int x,y;
        vector<int> f(g.size(),0);
        for(int i=0;i<g.size();i++)
            for(int j=0;j<g[i].size();j++){
                x=g[i][j];
                m[x].emplace_back(i);
                f[i]++;
            }
        queue<int> q;
        for(int i=0;i<g.size();i++)
        if(!f[i]) q.emplace(i);
        vector<int> ans;
        while(q.size()){
            x=q.front();
            q.pop();
            ans.emplace_back(x);
            for(int i=0;i<m[x].size();i++){
                y=m[x][i];
                f[y]--;
                if(!f[y])q.emplace(y);
            }
        }
        sort(ans.begin(),ans.end());
        return ans;
    }
};
posted @ 2021-08-05 21:43  黒川川  阅读(45)  评论(0)    收藏  举报