Leetcode 802 找到最终的安全状态(拓扑)

题目描述:

  在有向图中, 我们从某个节点和每个转向处开始, 沿着图的有向边走。 如果我们到达的节点是终点 (即它没有连出的有向边), 我们停止。现在, 如果我们最后能走到终点,那么我们的起始节点是最终安全的。 更具体地说, 存在一个自然数 K,  无论选择从哪里开始行走, 我们走了不到 K 步后必能停止在一个终点。哪些节点最终是安全的? 结果返回一个有序的数组。该有向图有 N 个节点,标签为 0, 1, ..., N-1, 其中 N 是 graph 的节点数.  图以以下的形式给出: graph[i] 是节点 j 的一个列表,满足 (i, j) 是图的一条有向边。

题解:

  根据题意分析,出度为0的点为最终安全点,一个点能够到达的点都是最终安全点的话,这个点也是安全点。那么对于这个有向图,我们反向建图,那么入度为0的点就是最终安全点,按照拓扑排序的思路依次处理下去,剩下的点就是不安全的点了。

AC代码:

  

class Solution {
public:
    //
    vector<int> Topo(int n,vector<vector<int>>& edge)
    {
        queue<int> que;
        vector<int> res;
        int vis[n+1];
        memset(vis,0,sizeof(vis));
        for(int i=0;i<n;i++)
        {
            if(degree[i] == 0) 
            {
                que.push(i);
                vis[i] = 1;
            }
        }
        
        while(!que.empty())
        {
            int now = que.front();
            que.pop();
            for(auto & next:edge[now])
            {
                degree[next]--;
                if(degree[next] == 0 && vis[next] == 0)
                {
                    que.push(next);
                    vis[next] = 1;
                }
            }
        }
        for(int i=0;i<n;i++) 
        {
            if(vis[i] == 1) res.push_back(i);
        }
        return res;
    }
    vector<int> eventualSafeNodes(vector<vector<int>>& graph) {
        int n = graph.size();
        if(n == 0) return {};
        vector<vector<int> > edge(n);
        memset(degree,0,sizeof(degree));
        for(int i=0;i<n;i++)
        {
            for(auto &next:graph[i])
            {
                edge[next].push_back(i);
                degree[i]++;
            }
        } 
        vector<int> ans = Topo(n,edge);
        return ans;
    }
private:
    int degree[10010];
};
原文地址:https://www.cnblogs.com/z1141000271/p/12696851.html