赞
踩
在有向图中, 我们从某个节点和每个转向处开始, 沿着图的有向边走。 如果我们到达的节点是终点 (即它没有连出的有向边), 我们停止。
现在, 如果我们最后能走到终点,那么我们的起始节点是最终安全的。 更具体地说, 存在一个自然数 K, 无论选择从哪里开始行走, 我们走了不到 K 步后必能停止在一个终点。
哪些节点最终是安全的? 结果返回一个有序的数组。
该有向图有 N 个节点,标签为 0, 1, …, N-1, 其中 N 是 graph 的节点数. 图以以下的形式给出: graph[i] 是节点 j 的一个列表,满足 (i, j) 是图的一条有向边。
示例:
输入:graph = [[1,2],[2,3],[5],[0],[5],[],[]]
输出:[2,4,5,6]
这里是上图的示意图。
提示:
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-eventual-safe-states
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
图的深度优先遍历:
class Solution { public: vector<int> eventualSafeNodes(vector<vector<int>>& graph) { if(graph.size() == 0) return vector<int>(); vector<int> safe(graph.size(), 0); for(int i = 0; i < graph.size(); ++i){ vector<int> visit(graph.size(), 0); if(safe[i] == 0) dfs(graph, safe, visit, i); } vector<int> res; for(int i = 0; i < safe.size(); ++i) if(safe[i] == 1) res.push_back(i); return res; } private: bool dfs(vector<vector<int>>& graph, vector<int>& safe, vector<int>& visit, int s){ if(graph[s].size() == 0 || safe[s] == 1){ safe[s] = 1; return true; } if(safe[s] == -1 || visit[s] == 1) return false; bool res = true; visit[s] = 1; for(int i = 0; i < graph[s].size(); ++i){ int t = graph[s][i]; res = dfs(graph, safe, visit, t); if(!res){ safe[s] = -1; return false; } } visit[s] = 0; if(res) safe[s] = 1; else safe[s] = -1; return res; } };
拓扑排序思想:
class Solution { public: vector<int> eventualSafeNodes(vector<vector<int>>& graph) { if(graph.size() == 0) return vector<int>(); vector<int> safe(graph.size(), 0); bool flag = true; while(flag){ flag = false; for(int i = 0; i < graph.size(); ++i){ int t = 0; if(safe[i] == 0){ for(int j = 0; j < graph[i].size(); ++j){ if(safe[graph[i][j]]) ++t; else break; } if(t == graph[i].size()){ safe[i] = 1; flag = true; } } } } vector<int> res; for(int i = 0; i < safe.size(); ++i) if(safe[i]) res.push_back(i); return res; } };
为了便于在程序中处理,可以生成一个顶点的入边的二维数组,题目中给的是顶点的出边的二维数组
class Solution { public: vector<int> eventualSafeNodes(vector<vector<int>>& graph) { if(graph.size() == 0) return vector<int>(); vector<vector<int>> rgraph(graph.size()); vector<int> outdegree(graph.size()); queue<int> q; vector<int> res; for(int i = 0; i < graph.size(); ++i){ for(int j = 0; j < graph[i].size(); ++j){//转化为入边 rgraph[graph[i][j]].push_back(i); } outdegree[i] = graph[i].size();//保存节点的出度 if(graph[i].size() == 0)//保存度为0的节点 q.push(i); } while(!q.empty()){ int f = q.front(); q.pop(); res.push_back(f); for(int i = 0; i < rgraph[f].size(); ++i){ --outdegree[rgraph[f][i]];//递减以该安全节点为弧头的节点的出度 if(outdegree[rgraph[f][i]] == 0)//递减完,出度为0则加入安全队列 q.push(rgraph[f][i]); } } sort(res.begin(), res.end()); return res; } };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。