DAG 图上的最长路问题 (兼模板)

12人阅读 评论(0) 收藏 举报
分类:

DAG图上可以做很多问题, 最常见的就是转化为求最长路问题. 那么求DAG上的最长路有很多方法, 其中所有的方法都离不开dp的思想, 只是用来求该dp的方式不同而已. 有拓扑序, DFS, BFS等. 最长路的模型也因为是点权还是边权有着不同, 注意写法就是了.
因为做过的一些题, 对于我来说有以下模板:
1: 常规的求某次最长路.
推荐用BFS. 优点是好写, 方便记路径等. 此时dp[i] 代表的是从起点到该点 i 的最优值.
板子:

struct node {
    int to,next,w;
}e[maxn];
int cnt, head[maxn];
void init() {
    Fill(head, -1);
    cnt = 0;
}
void add(int u,int v,int w) {
    e[cnt] = (node){v, head[u], w};
    head[u] = cnt++;
}
void solve() {
    queue<int>q; q.push(1);
    while(!q.empty()) {
        int u = q.front();
        q.pop();

        for(int i = head[u] ; ~i ; i = e[i].next){
            int v = e[i].to;
            int w = e[i].w + dp[u];
            if(dp[v] < w){
                dp[v] = w; // 记录路径可以在这里面加就行.
                if(dp[v] > maxx) maxx = dp[v];
                q.push(v);
            }
        }
    }
    printf("%d\n", maxx);
}

模板题

2: 用于求多次最长路的即可以从任意点出发到任意点结束的那种.
(即你要for一遍以每个点为起点做一次DAG的最长路的)
此时如果还是用bfs, 复杂度是O(n*(n+m))的. 不是很优秀, 所以我们用dfs, 此时的dp[i]代表的是从该条路径的叶子结点到 i 这个点的最优值, 所以如果某次遍历到某个点时其dp有值那么, 那么就可以不用更新下去了, 因为此时的值已经是最优的了. 相当于记忆化, 这样的复杂度为O(n+m).
板子如下:

const int maxn = 1e3+5;
int n, m, cas = 1;
int dp[maxn];
struct node {
    int to, next, w;
}e[maxn*maxn];
int cnt, head[maxn];
void init() {
    Fill(head, -1);
    cnt = 0;
}
void add(int u,int v,int w) {
    e[cnt] = (node){v, head[u], w};
    head[u] = cnt++;
}
int dfs(int u) {  // 这一段是主要部分.
    if (dp[u] > 0) return dp[u]; // 记忆化.
    for (int i = head[u] ; ~i ; i = e[i].next) {
        dp[u] = max(dp[u], dfs(e[i].to) + e[i].w);
    }
    return dp[u];
}
void solve() {
    scanf("%d%d", &n, &m);
    init(); Fill(dp, 0);
    for (int i = 1 ; i <= m ; i ++) {
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        add(u, v, w);
    }
    for (int i = 0 ; i < n ; i ++) {
        dfs(i);
    }
    int ans = 0;
    for (int i = 0 ; i < n ; i ++) {
        ans = max(ans, dp[i]);
    }
    printf("%d\n", ans);
}

测试题

查看评论

夕拾算法进阶篇:32)DAG最长路(动态规划DP)

之前介绍了DAG有向无环图以及拓扑排序,如何求解DAG的最长路,也就是所谓的“”关键路径”,但求解关键的路径的做法对初学者来说实在不易。因此下面介绍一种简便的方法,来求解DAG最长路(最短路的思想是一...
  • jiangpeng59
  • jiangpeng59
  • 2017-02-27 22:50:44
  • 2622

DAG最长路 uva437

题意:有n种立方体,每种无穷个。要求选一些立方体摞成一根尽量高的柱子,使得每个立方体的底面长宽严格小于它下方立方体的底面长宽解析:实际上每种立方体只有三次使用机会,先做预处理,给n*3种立方体编号。因...
  • qq_31607947
  • qq_31607947
  • 2018-03-05 20:34:41
  • 25

POJ-1949(DAG最长路径)

题目:http://poj.org/problem?id=1949 所有任务合起来构成一个DAG,因为任务可以并行,所以从无前驱的节点到无后继的节点的所有任务路径中,最耗时的那一条就是所需要的总...
  • uuuououlcz
  • uuuououlcz
  • 2014-12-02 11:22:05
  • 1221

The Tower of Babylon (DAG最长路算法模板)

点击打开链接   DAG图:在图论中,如果一个有向图无法从某个顶点出发经过若干条边回到该点,则这个图是一个有向无环图(DAG图)。 题意 有n种长宽高为x,y,z的砖头,每种都有...
  • Draven__
  • Draven__
  • 2017-08-20 21:34:45
  • 371

DAG 图上的最长路问题 (兼模板)

DAG图上可以做很多问题, 最常见的就是转化为求最长路问题. 那么求DAG上的最长路有很多方法, 其中所有的方法都离不开dp的思想, 只是用来求该dp的方式不同而已. 有拓扑序, DFS, BFS等....
  • Anxdada
  • Anxdada
  • 2018-04-17 21:49:16
  • 12

nyoj 10 skiing(DAG上的最长路,备忘录方法)

skiing 时间限制:3000 ms  |  内存限制:65535 KB 难度:5 描述 Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当...
  • GreenHandCGL
  • GreenHandCGL
  • 2016-05-12 17:44:18
  • 376

强连通分量,DAG上的最长路,记忆化搜索(最大团,UVA 11324)

一点手误,搞WA了。。。 代码 #include #define rep(i,a,b) for(int i=a;i
  • xl2015190026
  • xl2015190026
  • 2017-02-09 17:57:47
  • 174

CF #459 D. MADMAX(DAG最长路)

http://codeforces.com/contest/918/problem/D D. MADMAX time limit per test 1 second ...
  • winter2121
  • winter2121
  • 2018-01-30 11:32:44
  • 206

DAG上的动态规划

1、嵌套矩形
  • u010607031
  • u010607031
  • 2014-07-15 21:59:48
  • 417

DAG上的动态规划两题

NYOJ16 嵌套矩形 其实就是刘汝佳紫书中的题目。而且不要求字典序输出。开始想着按照自己的思路写的,后来发现都错了,因为它的起点是不固定的,开始想当然以为起点固定。 思路:把输入的每个矩形当做是...
  • RockyHOO1209
  • RockyHOO1209
  • 2017-12-01 13:29:09
  • 103
    个人资料
    持之以恒
    等级:
    访问量: 6万+
    积分: 5250
    排名: 6470
    文章分类