首页 > 其他 > 详细

【暖*墟】#动态规划# 基环树DP的学习与练习

时间:2019-02-22 18:08:04      阅读:251      评论:0      收藏:0      [点我收藏+]

 

因为弃置了 四边形不等式优化 ,所以DP的任务还剩下 基环树DP / 插头DP / 动态DP

当然,树形DP / 状压DP / 数位DP / 斜率优化DP 也还是要练习的......

 

一 . 基环树的定义

基环树:无向图,在一颗树的基础上,添加一条边。环上每个点都是树根。

技术分享图片

如果进行正常的DP,在环中是无法处理的。所以要把环拆开。

假设要拆开的点是环上连在一起的u、v,这两个点存在限制关系(比如不同时选)。

在拆开后,分别讨论 选择u不选择v选择v不选择u 两种情况即可。

 

二 . “找环”操作

在基环树上dfs,找到一个在此结点之前走过的相邻结点、就开始记录环。

vector<int> G[MAXN]; //基环树

int fa[MAXN]; //dfs时的父亲

int dfn[MAXN], idx;  //访问的时间

int loop[MAXN], cnt; //

void get_loop(int u) {
    dfn[u] = ++ idx; //记录dfn序
    for (int i = 0; i < G[u].size(); i ++) {
        int v = G[u][i]; if(v == fa[u]) continue ;
        if(dfn[v]) { //找到了环
            if(dfn[v] < dfn[u]) continue ;
            loop[++ cnt] = v;
            for ( ; v != u; v = fa[v])
                loop[++ cnt] = fa[v];
        } else fa[v] = u, get_loop(v); //继续递归
    }
}

 

三 . 有向的基环树

基环内向树:每个点出度为1(因此每个环上点的子树,儿子指向父亲)。

技术分享图片

 

基环外向树:每个点入度为1(因此每个环上点的子树,父亲指向儿子)。

  • 将上图的所有边反转一下,就是基环外向树。

 

四 . 具体代码实现

 

【暖*墟】#动态规划# 基环树DP的学习与练习

原文:https://www.cnblogs.com/FloraLOVERyuuji/p/10419674.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!