关于《算法概论》中,使用dfs对图进行标记的操作的实践
2018-01-05 20:42
183 查看
其实本身是在做leetcode 685. Redundant Connection II
题目说一定以根节点开头,但实际好像并非如此…感觉被坑了。
原先的思路是利用书中所说的dfs,选好根节点,进行pre和post标记,根据每个节点的标记判断前向边,横跨边,回边。
不过测试会出现第一个边是需要删除的边的情况。。。
就权当对bfs的边判断的练手了
注:该段代码并不能通过测试(开头不是根的情况无法通过)
但还是有意义的。利用bfs对各个节点定下标记:
通过pre标记和post标记的大小判断边的种类
题目说一定以根节点开头,但实际好像并非如此…感觉被坑了。
原先的思路是利用书中所说的dfs,选好根节点,进行pre和post标记,根据每个节点的标记判断前向边,横跨边,回边。
不过测试会出现第一个边是需要删除的边的情况。。。
就权当对bfs的边判断的练手了
class Solution { public: bool isBack(int preA, int postA, int preB, int postB) { if (preB < preA && preA < postA && postA < postB) return true; return false; } bool isCross(int preA, int postA, int preB, int postB) { if (preB < postB && postB < preA && preA < postA) return true; return false; } bool isForward(int preA, int postA, int preB, int postB) { if (preA < preB && preB < postB && postB < postA) return true; return false; } vector<int> findRedundantDirectedConnection(vector<vector<int>>& edges) { vector<vector<int>> graph; vector<bool> visit; int N = edges.size(); graph.resize(N+1); visit.resize(N+1); for (int i = 0; i < N+1; i++) visit[i] = false; for (auto x: edges) { graph[x[0]].push_back(x[1]); } //dfs stack<int> s; int tag = 0; vector<int> pre; vector<int> post; pre.resize(N+1); post.resize(N+1); s.push(edges[0][0]); visit[edges[0][0]] = true; pre[edges[0][0]] = tag++; while (!s.empty()) { int cur = s.top(); //cout << cur << endl; bool find = false; for (int i = 0; i < graph[cur].size(); i++) { if (!visit[graph[cur][i]]) { s.push(graph[cur][i]); visit[graph[cur][i]] = true; pre[graph[cur][i]] = tag++; find = true; break; } } if (!find) { post[cur] = tag++; s.pop(); } } vector<int> result; for (int i = edges.size()-1; i >= 0; i--) { if (isBack(pre[edges[i][0]], post[edges[i][0]], pre[edges[i][1]], post[edges[i][1]])|| isCross(pre[edges[i][0]], post[edges[i][0]], pre[edges[i][1]], post[edges[i][1]])) { result.push_back(edges[i][0]); result.push_back(edges[i][1]); return result; } } if (result.size() == 0) { for (int i = edges.size()-1; i >= 0; i--) { if (isForward(pre[edges[i][0]], post[edges[i][0]], pre[edges[i][1]], post[edges[i][1]])) { result.push_back(edges[i][0]); result.push_back(edges[i][1]); return result; } } } return result; } };
注:该段代码并不能通过测试(开头不是根的情况无法通过)
但还是有意义的。利用bfs对各个节点定下标记:
通过pre标记和post标记的大小判断边的种类
相关文章推荐
- LR关于对参数进行截取操作的实践
- objective-c中对象所有权的内存管理(关于set,get方法),以及如何使用@property来进行简易操作
- objective-c中对象所有权的内存管理(关于set,get方法),以及如何使用@property来进行简易操作(九)
- 关于Android Studio 使用SVN进行 项目回滚操作
- 关于使用phpMyAdmin进行可视化操作Mysql数据库
- LR关于对参数进行截取操作的实践
- [课堂实践与项目]手机QQ客户端--4期(SQLite的加入,注册,找回,登录界面的修改):建立关于QQ注册类,使用SQLite进行存储,
- 关于SubSonic3.0插件使用Json反序列化获得的实体进行更新操作时,只能执行添加而不能执行修改(编辑)操作的处理
- 关于Jpa使用Update方法进行更新操作,却没有同步到数据库的原因
- 关于ISDN使用R3640路由器进行配置操作实例
- 关于使用hunt进行会话劫持的实践
- objective-c中对象所有权的内存管理(关于set,get方法),以及如何使用@property来进行简易操作(九)
- 关于SubSonic3.0插件使用Json反序列化获得的实体进行更新操作时,只能执行添加而不能执行修改(编辑)操作的处理
- 关于Linux下使用expdp和impdp命令对Oracle数据库进行导入和导出操作
- 关于SubSonic3.0插件使用实体进行更新操作时(执行T.Update()或T.Save()),某些列无法进行修改操作的问题处理
- 关于在子线程中在run方法执行完之后通知主线程进行操作的方法。(Toast在子线程中无法使用)
- 关于Linux下使用expdp和impdp命令对Oracle数据库进行导入和导出操作
- 关于使用js进行表单提交操作引发的表单重复提交问题
- 关于使用定义函数来实现对于数组c中的元素进行筛选最大值最小值,计算平均值等操作
- Day29-关于类加载器在读取properties文件上的运用,轻松使用绝对路径,直接在包的根目录下进行操作