有向图的dfs树
有向图的dfs树包含4种边:
1.树边。每次搜索找到一个还没有被访问过的节点时,生成一条树边
2.返祖边。指向祖先节点的边
3.横叉边。搜索时遇到了一个已经访问过的节点,但是这个节点并不是当前节点的祖先节点
4.前向边。搜索时遇到已经访问过的子树中的节点
图中节点编号为dfs序的编号
绿色代表树边,黄色代表返祖边,红色代表横叉边,蓝色代表前向边
tarjan算法
tarjan算法在有向图的dfs树生成的过程中计算强连通分量
只有反祖边可以形成强连通分量
设立两个数组:
1.dfn数组。存储有向图的dfs序。
2.low数组。存储某个节点可以到达的dfn值最小的祖先节点的dfn值
const int maxn=10010,maxm=100010;
int dfn[maxn],low[maxn],stk[maxn],scc[maxn],top,dfscnt,scccnt;
void tarjan(int u){
dfn[u]=low[u]=++dfscnt;
stk[++top]=u;
for(int v:g[u]){
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!scc[v]) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
++scccnt;
while(1){
int v=stk[top--];
scc[v]=scccnt;
if(v==u) break;
}
}
}