On the point of the cut algorithm

Cut the concept of point

Undirected connected graphs, in which if a connection point and this point all edges removed, FIG no longer in communication, then this point is called the cut points (cut vertex / articulation point).

For example, in the figure, the points 0,3 are cut, because the 0 and 3 after removing any, is no longer communicating FIG. If 0 is removed, and the map is divided into two connected components 1, 3, 4; 3, if removed, then FIG 4 is divided into two connected components and 0,1,2.

404

How demand cut point

Tarjan algorithm for use cutpoint (note, there is a component of the connected components algorithm is also called Tarjan algorithm, this algorithm is similar, see here Wallpaper ). (Tarjan, full name Robert Tarjan, American computer scientist.)

First, a root node is selected, from the root node through the entire map (used DFS).

For the root node, a cut point judgment is not very simple - it calculates the number of sub-tree, if there are 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]represents the first of several vertex u is (first) visit, low[u]expressed its point vertex u subtree by a non-parent-child edges (back side), can be traced back to the earliest point ( dfnminimum) dfnvalue (but not through the connection edge to its parent node u). For the side (u, v), if low[v]>=dfn[u], at this time uthat cut.

But here there is a problem: how to calculate low[u].

Suppose the current vertex u, by default low[u]=dfn[u], that is, at the earliest dating back to itself.

There is an edge (u, v), if vnot visited, continue DFS, DFSEnd,low[u]=min(low[u], low[v]) ;

If v(and visited unot vthe father), it does not continue DFS, and there must be dfn[v]<dfn[u],low[u]=min(low[u], dfn[v]).

Reference Hirofumi: Https://Www.Cnblogs.Com/collectionne/p/6847240.Html

Code

#include<bits/stdc++.h>
using namespace std;
const int MAXN=20000;
const int MAXM=100000+10;
int dfn[MAXN],low[MAXN];
bool cut[MAXN];
int ans;
int n,m,deep;
struct Node
{
    int to,next;
}edge[MAXM*2];
int cnt,head[MAXN];
inline int read()
{
    int tot=0;
    char c=getchar();
    while(c<'0'||c>'9')
        c=getchar();
    while(c>='0'&&c<='9')
    {
        tot=(tot<<1)+(tot<<3)+c-'0';
        c=getchar();
    }
    return tot;
}
inline void add(int x,int y)
{
    edge[++cnt].to=y;
    edge[cnt].next=head[x];
    head[x]=cnt;
}
inline void tarjan(int u,int father)
{
    int tot=0;
    low[u]=dfn[u]=++deep;
    for(int i=head[u];i;i=edge[i].next)
    {
        int v=edge[i].to;
        if(!dfn[v])
        {
            tarjan(v,u);
            low[u]=min(low[u],low[v]);
            if(low[v]>=dfn[u]&&u!=father)cut[u]=1;
            if(u==father)tot++;
        }
        low[u]=min(low[u],dfn[v]);
    }
    if(u==father&&tot>=2)cut[u]=1;
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=m;i++)
    {
        int x=read(),y=read();
        add(x,y);add(y,x);
    }
    /*for(int i=1;i<=n;i++)
        for(int j=head[i];j;j=edge[j].next)
            cout<<i<<" "<<edge[j].to<<endl;*/
    for(int i=1;i<=n;i++)
        if(!dfn[i])tarjan(i,i);
    for(int i=1;i<=n;i++)   
        ans+=cut[i];
    printf("%d\n",ans);
    for(int i=1;i<=n;i++)
        if(cut[i])printf("%d ",i);
    printf("\n");
    return 0;
}

Here are some exercises

Guess you like

Origin www.cnblogs.com/hulean/p/11919835.html