主要是给自己的,一些易忘知识点的总结吧。

 

 

 

 

割点:根的有俩儿子就是割点,其他的点如果子树中有儿子连接不到它祖先那里去就是割点(即存在low[son[u]]>=dfn[u])。

桥:结点u的子结点v的后代通过反向边只能连回v(low[v]>dfn[u])。

void tarjan(int u){
    dfn[u]=low[u]=++order;
    bool flag=false;
    for (int i=0;i<edge[u].size();i++){
        int v=edge[u][i];
        if(!dfn[v]){
            son[u]++;
            father[v]=u;
             tarjan(v);
            if(low[v]>=dfn[u]) flag=true;
            //点u为割点 
            if(low[v]>dfn[u]) cutedge.push_back(make_pair(min(v,u),max(v,u)));
            //边v-u为割边 
            low[u]=min(low[u],low[v]);
        }
        else if(v!=father[u]) low[u]=min(low[u],dfn[v]);
    }
    //根节点若有两棵或两棵以上的子树则该为割点
    //非根节点若所有子树节点均没有指向u的祖先节点的回边则为割点
    if((father[u]==0&&son[u]>1)||(father[u]&&flag)) cutpoint.push_back(u);
}
View Code

相关文章: