反向图+拓扑排序 or 染色:Leetcode802 找到最终的安全状态

梦想不抛弃苦心追求的人,只要不停止追求,你们会沐浴在梦想的光辉之中。再美好的梦想与目标,再完美的计划和方案,如果不能尽快在行动中落实,最终只能是纸上谈兵,空想一番。只要瞄准了大方向,坚持不懈地做下去,才能够扫除挡在梦想前面的障碍,实现美好的人生蓝图。反向图+拓扑排序 or 染色:Leetcode802 找到最终的安全状态,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

反向图+拓扑排序 or 染色:Leetcode802 找到最终的安全状态

问题:

在这里插入图片描述
在这里插入图片描述

思路:

反向图+拓扑排序:

对于一个节点 u,如果我们从 u 开始任意行走能够走到一个环里,那么 u 就不是一个安全的节点。换句话说,u 是一个安全的节点,当且仅当 u 直接相连的节点(u 的出边相连的那些节点)都是安全的节点。

对于没有出度的节点,一定是最终安全的节点,而仅直接指向它的节点(出度为1,且指向没有出度的节点)也是最终安全的节点。以此类推,这样我们可以将所有的边全部反向,首先所有没有任何入度的节点都是安全的,我们把这些节点全部移除。随后新的图中没有任何入度的节点都是安全的。

我们发现这种做法实际上就是对图进行拓扑排序,将原问题转化为了拓扑排序问题

染色:

对于每个节点,有三种染色方法:白色表示节点尚未被访问(用0表示),灰色表示该节点在此轮搜索中已被访问过或该节点在环中(用1表示),黑色表示该节点的所有相连节点已被访问,且该节点不在环中(用2表示)

对每个节点进行DFS,DFS函数的功能为判断该节点是否为黑色节点或能被染成黑色。
进入DFS后,判断该节点是否已经被染过色,若已染成黑色,直接返回TRUE,染成灰色直接返回FALSE
若未被染色,先将其染成灰色
只有与该节点相连的所有节点都为黑色节点或能被染成黑色,该节点才能被染成黑色,并返回TRUE(u 是一个安全的节点,当且仅当 u 直接相连的节点都是安全的节点),否则返回FALSE

代码:

反向图+拓扑排序:

class Solution {
public:
    vector<int> eventualSafeNodes(vector<vector<int>>& graph) {
        int* indegree;
        vector<int> ans;
        indegree=(int*)malloc( graph.size()*sizeof(int) );
        int i;
        for( i=0;i<graph.size();i++ )
        {
            indegree[i]=0;
        }
        int j;
        for( i=0;i<graph.size();i++ )
            indegree[i]=graph[i].size();
        vector<vector<int>> reverse_graph;
        for( i=0;i<graph.size();i++ )
            reverse_graph.push_back( vector<int>() );
        for( i=0;i<graph.size();i++ )
        {
            for( j=0;j<graph[i].size();j++ )
                reverse_graph[ graph[i][j] ].push_back(i);
        }
        stack<int> st;
        for( i=0;i<graph.size();i++ )
        {
            if( indegree[i]==0 )
                st.push( i );
        }
        int temp;
        while( st.size()!=0 )
        {
            temp=st.top();
            ans.push_back(temp);
            st.pop();
            for( i=0;i<reverse_graph[temp].size();i++ )
            {
                indegree[ reverse_graph[temp][i] ]--;
                if( indegree[ reverse_graph[temp][i] ]==0 )
                    st.push( reverse_graph[temp][i] );
            }
        }
        sort( ans.begin(),ans.end() );
        return ans; 
    }
};

染色:

class Solution {
public:
    bool dfs( int i,vector<vector<int>>& graph,int* color )
    {
        if( color[i]>0 )
            return color[i]==2;
        color[i]=1;
        int j;
        for( j=0;j<graph[i].size();j++ )
        {   
            if( color[ graph[i][j] ]==2 )
                continue;
            else if( color[ graph[i][j] ]==1 || !dfs( graph[i][j],graph,color ) )
                return false;
        }
        color[i]=2;
        return true;
    }
    vector<int> eventualSafeNodes(vector<vector<int>>& graph) {
        int* color;
        color=(int*)malloc( graph.size()*sizeof(int) );
        int i;
        for( i=0;i<graph.size();i++ )
            color[i]=0;
        vector<int> ans;
        for( i=0;i<graph.size();i++ )
        {
            if( dfs( i,graph,color ) )
                ans.push_back(i);
        }
        return ans;
    }
};

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/153842.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!