基环树/环套树 学习笔记
前置知识
- 会 tarjan、拓扑排序、dfs 一棵树;
- 知道环和图的定义。
目录
- Part 1:什么是基环树
- Part 2:找环的方法
- Part 3:练习
Part 1:什么是基环树
基环树是一个由 n 个点 n 条边组成的图,其中包含一个环,而且是连通的。
Part 2:找环的方法
1. tarjan
void tarjan(int u,int fa){
dfn[u]=low[u]=++idx;
st.push(u);
for(int i=0;i<g[u].size();++i){
int v=g[u][i];
if(v==fa)continue;
if(dfn[v]==0){
tarjan(v,u);
low[u]=min(low[u],low[v]);
}
else low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
cnt++;
int v;
do{
v=st.top();
st.pop();
scc[v]=cnt;
} while(u!=v);
}
return ;
}
2. 拓扑排序
xxxxxxxxxx
void tpsort(){
queue<int> q;
for(int i=1;i<=n;++i){
if(in[i]==1) q.push(i);
}
while(q.size()){
int u=q.front();
q.pop();
for(int i=0;i<g[u].size();++i){
int v=g[u][i];
if(in[v]>1){
--in[v];
if(in[v]==1) q.push(v);
}
}
}
}
3. dfs
xxxxxxxxxx
void findCircle(int u,int fa){
vis[u]=1;
for(int i=0;i<g[u].size();++i){
int v=g[u][i];
if(v==fa) continue;
if(vis[v]){
flag=true,l=u,r=v;
continue;
}
findCircle(v,u);
}
}