Template - strongly connected component / cutpoint / Bridge - Tarjan

int dfn[N], low[N], dfncnt, s[N], tp;
int scc[N], sc;  // 结点 i 所在 scc 的编号
int sz[N];       // 强连通 i 的大小
void tarjan(int u) {
    low[u] = dfn[u] = ++dfncnt, s[++tp] = u;
    for(int i = h[u]; i; i = e[i].nex) {
        const int &v = e[i].t;
        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]) {
        ++sc;
        while(s[tp] != u)
            scc[s[tp]] = sc, sz[sc]++, --tp;
        scc[s[tp]] = sc, sz[sc]++, --tp;
    }
}

Cut point:
is easy for the root node, a cut point judgment is not - calculating its subtree, if more than two subtrees i.e., that cut. Because if you remove this point, which two sub-trees can not reach each other.
For non-root node, the point is not to judge cut some trouble. We maintain two arrays dfn [] and low [], dfn [u] u represents the apex of the first of several to be (first) access, low [u] u represents the apex point and sub-tree, by the side back, can go back to the first point (dfn minimum) value dfn (but not the parent node through the connection edge u). For the edge (u, v), if low [v]> = dfn [ u], u is cut at this time point.

Suppose the current vertex u, the default low [u] = dfn [u ], i.e., only the first back to itself.
There is an edge (u, v), then if v has not visited, continue DFS, DFS finished, low [u] = min ( low [u], low [v]);
if v visited (and u instead of v father), there is no need to continue the DFS, there must dfn [v] <dfn [u ], low [u] = min (low [u], dfn [v]).

The following u == fa mean u == ROOT, he would like to pass a fa

void tarjan (int u,int fa)
{
    DFN[u]=LOW[u]=++idx;
    int child=0;
    for (int i=head[u];i!=0;i=pre[i].mark)
    {
        int nx=pre[i].nxt;
        if (!DFN[nx])
        {
            tarjan (nx,fa);
            LOW[u]=min (LOW[u],LOW[nx]);
            if (LOW[nx]>=DFN[u]&&u!=fa)
                cut[u]=1;
            if(u==fa)
                child++;
        }
        LOW[u]=min (LOW[u],DFN[nx]);
    }
    if (child>=2&&u==fa)
        cut[u]=1;
}

 for (int i=1;i<=n;i++)
        if (DFN[i]==0)
            tarjan (i,i);
    for (int i=1;i<=n;i++)
        if (cut[i])
            tot++;

Cutting edge:

And almost cut point, also called the cutting bridge.
For an undirected graph, a deleted if the number of edges connected component is increased, the bridge is said to this edge or cutting edge.
Realization
and cut point almost as long as a change: low (v)> dfn ( u) on it, and no need to consider the root of the problem.

Cutting edge is and is not the root of the matter, we find the original cut point of time is impossible without the guidance of v u is the parent node back to the ancestors (including the parent), the vertex u is cut point. If low (v) == dfn (u) may also return to the parent node represents, if not a vertex v ancestors did not return to his father's road back to another one, then (u, v) of this side is the cutting edge.

Guess you like

Origin www.cnblogs.com/Yinku/p/11361532.html