基环树,图内找环技巧
我开始的想法是,DFS记录当前正在走的一条路径,当遇到曾经走过的点,那么就成环,然后fa往回跳记录即可。
但是我发现,没有办法记录两个点构成的环,因为我们在dfs的时候,通常会将连接父亲的点重复边,一般会 continue
,所以这就导致我们解决不了两个点的环。
找环代码
void dfs1(int u,int pre)
{
fa[u]=pre; vis2[u]=++num;
for (int i=head[u];i;i=e[i].nxt)
{
int v=e[i].v;
if (v==pre) continue;
if (vis2[v])
{
if (vis2[v]<vis2[u]) continue;
int x=v;
while (x!=u)
{
st[++top]=x;
vis[x]=1;//标记在环上
x=fa[x];
}
st[++top]=u;
vis[u]=1;
}
dfs1(v,u);
}
原理,vis2中存储的是每个点的dfs序,我们知道对于一个环,我们会在dfs时遇到两次,第一次是子节v点访问到曾祖父节点,形成环,第二次是回溯时,回溯到曾祖父节点,然后继续枚举该点连接的其他点时,枚举到子节点。对于第一次相遇,其实和我之前的想法是一样,我们普遍认为,最好想的找环就是遇到曾经遇到的,但是解决不了上述的问题。
而第二次相遇就可以很好的避免上述问题,哪怕是只有两个点的自环,v 节点也会被同样访问两次,因为建边的时候会建立两组相同的边。

3919

被折叠的 条评论
为什么被折叠?



