Longest Path in DAG 有向无环图中的最长路径问题
来源:互联网 发布:黑河广电网络 编辑:程序博客网 时间:2024/05/22 04:49
第一次看见这个问题是 《算法导论》Chapter 15 动态规划课后思考题15-1的题目。
本文主要参考:http://www.geeksforgeeks.org/find-longest-path-directed-acyclic-graph/
问题描述
给定一个有向图(Directed Acyclic Graph)以及一个起点s,求该图中s点到其余所有点的最长路径。
题解
正如算法导论中提到的那样,给定有向图的最长路径问题并不如有向图最短路径那么简单,因为它不具备 最优子结构(Optimal Substructure Property)。实际上,该问题是NP-Hard问题。
但是,有向无环图的最长路径问题确有一个线性时间的解。这种思想和解决DAG最短路径问题相似,采用拓扑排序(Topological Sorting )。
我们将求得DAG的拓扑序列,那么对于拓扑序列,就可以用动态规划来处理。由拓扑序列的性质可以断定在拓扑序列该问题具有最优子结构。(当前问题的解包含子问题的解)
我们定义dist[v]为起点s到v的最长路径,那么递归关系为:
dist[v] = max{dist[pre] + weight(pre->v)},pre是一条指向v的边的起点
这里我们从左到右遍历拓扑序列,对于当前点i,更新其邻接点的dist。
需要强调的是这里的拓扑排序的实现方式是基于Dfs,需要掌握。
代码
#include <iostream>#include <vector>#include <stack>#include <map>#include <cstring>#include <string>#include <algorithm>//#include <cmath> #include <utility>#include <unordered_map>#include <set>#include <queue>#include <cmath>#include <list>#include <functional>using namespace std;//定义邻接点类class AdjListNode { int val; int weight;public: AdjListNode(int _v, int _w) { val = _v; weight = _w; } int getV() { return val; } int getWeight() { return weight; }};//定义图类class Graph { int num_v; list<AdjListNode> *adj; void TopologicalSortUtil(int v, bool visited[], stack<int> &Stack);public: Graph(int v); void addEdge(int u, int v, int weight); void LongestPath(int s);};Graph::Graph(int v) { num_v = v; adj = new list<AdjListNode>[v];}//Dfs求其拓扑排序void Graph::TopologicalSortUtil(int v, bool visited[], stack<int> &Stack) { visited[v] = true; list<AdjListNode>::iterator i; for (i = adj[v].begin(); i != adj[v].end(); i++) { if (visited[(*i).getV()] == true) continue; TopologicalSortUtil((*i).getV(), visited, Stack); } Stack.push(v);}void Graph::addEdge(int u, int v, int weight) { AdjListNode next(v, weight); adj[u].push_back(next);}void Graph::LongestPath(int s) { bool *visited = new bool[num_v]; int *dist = new int[num_v]; stack<int> Stack; for (int i = 0; i < num_v; i++) { visited[i] = false; dist[i] = INT_MIN; } //初始化所有dist为INT_MIN,然后dist[s] = 0. dist[s] = 0; //求其拓扑序列 for (int i = 0; i < num_v; i++) { if (!visited[i]) { TopologicalSortUtil(i, visited, Stack); } } while (!Stack.empty()) { int u = Stack.top(); Stack.pop(); if (dist[u] == INT_MIN) continue;//如果此时仍不可达,则跳过该点 list<AdjListNode>::iterator i; for (i = adj[u].begin(); i != adj[u].end(); i++) { if (dist[(*i).getV()] < dist[u] + (*i).getWeight()) { dist[(*i).getV()] = dist[u] + (*i).getWeight(); } } } for (int i = 0; i < num_v; i++) { if (i) printf(" "); (dist[i] == INT_MIN) ? printf("INF") : printf("%d", dist[i]); }}int main() { Graph g(6); g.addEdge(0, 1, 5); g.addEdge(0, 2, 3); g.addEdge(1, 3, 6); g.addEdge(1, 2, 2); g.addEdge(2, 4, 4); g.addEdge(2, 5, 2); g.addEdge(2, 3, 7); g.addEdge(3, 5, 1); g.addEdge(3, 4, -1); g.addEdge(4, 5, -2); int s = 1; cout << "Following are longest distacnes from soucre vertex " << s << "\n"; g.LongestPath(s); return 0;}
总结
写这篇博文目的:
1.Dfs外加一个for循环求DAG的拓扑排序。
2.很少写这种面向对象的代码,所以写一写练习一下。
阅读全文
0 0
- Longest Path in DAG 有向无环图中的最长路径问题
- DAG有向无环图
- DAG 有向无环图
- 有向无环图DAG
- 有向图中的最长路径
- 有向无环图(DAG)的最小路径覆盖
- 有向无环图(DAG)的最小路径覆盖
- 有向无环图(DAG)的最小路径覆盖
- 有向无环图(DAG)的最小路径覆盖
- DAG(有向无环图) ------应用
- DAG是有向无环图
- 【笔试/面试】—— 有向无环图(DAG)的最短路径问题(动态规划)
- LeetCode 329. Longest Increasing Path in a Matrix(矩阵内的最长递增路径)
- leetcode解题之329. Longest Increasing Path in a Matrix Java版 (最长上升路径)
- 算法导论 思考题 15-1(有向无环图中的最长简单路径)
- 求以邻接矩阵存储的有向无环图中的最长路径
- DAG? 判断是否为有向无环图DAG
- hdu 1151 DAG图(有向无环图)的最小路径覆盖
- C++中的运算符重载
- linux Privilege to run Oracle catprpc.sql
- 互补滤波原理
- Windows下用Anaconda安装TensorFlow,并在pycharm中使用
- C++编程笔记:使用WinHTTP实现HTTP访问(解决接收UTF8数据乱码问题)
- Longest Path in DAG 有向无环图中的最长路径问题
- 【Scikit-Learn 中文文档】12 决策树
- ArrayList集合
- 分页中PageBean的创建
- POJ
- 【Scikit-Learn 中文文档】13 集成方法
- 《kubernetes-1.8.0》08-addon-dashboard
- android 字体上添加横线,字体下面添加下划线
- 快速排序算法