版权声明:本文为hzy原创文章,未经博主允许不可随意转载。 https://blog.csdn.net/Binary_Heap/article/details/82080267
基环树是一种图,它由一个环组成,环上每个点都是一棵树点树根,所以称为基环树。当然,一棵树上连一条边也会变成基环树。
下图是一个基环树.
基环树一般分成环和树来分别处理(显然环的处理较为麻烦),那首先得找到环.
找环
大概就是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 骑士