leetcode802——Find Eventual Safe States

题目大意:从一个结点出发,最终能走到一个没有出边的点,那么这个起始点称为安全点。给出有向图的邻接表,问图里哪些点是安全点。

分析:

方法一:dfs。这道题的意思就是看从哪些点出发没有能回到原点的环存在。给图中的结点上色,初始化为0号色(color[i]=0表示没访问过该结点),dfs时遍历到的结点染1号色(表示访问过该节点),遍历邻接表判断如果无环则该节点染2号色(表示安全无环)。

方法二:拓扑排序。安全节点=无出边。将图中的所有边反向(注意题中给的graph是邻接表,不是leetcode210中给出的边集合),此时安全节点=无入边的点(入度为0),与安全节点相连的点也是安全节点,所以将入度为0的点和它的出边删掉后,剩下的入度为0的点也是安全节点,这一过程就是拓扑排序的过程。

代码:

方法一:dfs

class Solution {
public:    
    vector eventualSafeNodes(vector>& graph) {        
        int n = graph.size();        
        vector color(n);        
        vector ans;        
        for(int i = 0;i < n;i++){  //dfs每个结点判断是否有环    
            if(dfs(i,color,graph))                                                                                                                                                                                
                ans.push_back(i);          
        }        
        return ans;    
    }    
    bool dfs(int i,vector& color,vector>& graph){        
        if(color[i]) return color[i] == 2;  //如果染色是安全状态2就返回true        
        color[i] = 1;  //初始染1号色,相当于标记这次dfs过程中访问过它,但它的状态不确定是否安全                         
        for(auto nei : graph[i]){  
            // 邻接节点不安全 || 邻接节点的邻接节点不安全
            if(color[nei] == 1 || !dfs(nei,color,graph))                
                return false;        
        }        
        color[i] = 2;        
        return true;    
    }
};

方法二:拓扑排序

class Solution {
public:
    vector eventualSafeNodes(vector>& graph) {
        vector> pre(graph.size());  //记录每个节点的后续结点
        vector degree(graph.size(),0);  //记录每个结点的入度
        for (int i = 0;i < graph.size();i++) {
            for(int j = 0;j < graph[i].size();j++){
                degree[i]++;
                pre[graph[i][j]].push_back(i);
            }
        }
        queue q;  //队列维护入度为0的结点
        for(int i = 0;i < graph.size();i++){
            if(degree[i] == 0) q.push(i);
        }
        vector schedule;
        while(!q.empty()){
            int now = q.front();
            q.pop();
            schedule.push_back(now);
            for(int i = 0;i < pre[now].size();i++){
                degree[pre[now][i]]--;
                if(degree[pre[now][i]] == 0) q.push(pre[now][i]);
            }
        }
        sort(schedule.begin(),schedule.end());
        return schedule;
    }
};

 

你可能感兴趣的:(搜索-dfs,图论)