反向圖+拓撲排序 or 染色:Leetcode802 找到最終的安全狀態

反向圖+拓撲排序 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;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章