「学习笔记」基环树

基环树是一种图,它由一个环组成,环上每个点都是一棵树点树根,所以称为基环树。当然,一棵树上连一条边也会变成基环树。

下图是一个基环树.

基环树

基环树一般分成环和树来分别处理(显然环的处理较为麻烦),那首先得找到环.

找环

大概就是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;
    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(因此每个环上点的子树,父亲指向儿子)

上图把所有边反一下,就是个基环外向树.

推荐例题

(Tips:博客中有讲解qwq!)

ZJOI2008 骑士

©️2020 CSDN 皮肤主题: 精致技术 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值