tarjan- undirected graph (cutpoint request)

First, the basic concept

1, cut points: undirected connected graphs, if a deleted point, FIG become none, called change point cut point.

2, the bridge: undirected connected graphs, if one edge is removed, the whole would not divided into two parts (i.e. do not communicate the entire FIG.) To the FIG., Such an edge to become the bridge.

3, double-point communication component: No cutting point maximal connected subgraph

        Between any two points you have at least two non ⾄ without the same side of the path

4, double-side communication component: No maximum communication sub-cutting edge of FIG.

        ⾄ between any two points has at least two (in addition to start and end points) does not pass through the same point of the path

 

Two, tarjan find cut points

1) When the current node is the root, the conditions become cut point is "to have more than one sub-tree" (if only a sub-tree, remove this point has no effect if there are two sub-tree, remove this point, two communication with the satellites is not subtree)

2) when the current node is not the root, with the proviso that "low [v]> = dfn [u]", i.e. after the traversal of points u, can be turned up, up to u. (If u turn upward, it would have the ring, after removing u, FIG still communicating.) Therefore, to ensure that the most up to v u turn can

 

Luo Gu board questions

#include<cstdio>
#include<algorithm> 
using namespace std;

inline int read()
{
    int sum = 0,p = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
            p = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        (sum *= 10) += ch - '0';
        ch = getchar();
    }
    return sum * p;
}

const int maxn = 20005,maxm = 100005;
int n,m,tot;
int dfn[maxn],low[maxn],tim;
int cnt,head[maxn];
struct edge
{
    int nxt,to;
}e[maxm * 2];
bool mrk[maxn];

void add(int x,int y)
{
    e[++cnt].nxt = head[x];
    e[cnt].to = y;
    head[x] = cnt;
}

void tarjan(int u,int fa)
{
    dfn[u] = low[u] = ++tim;
    int child = 0;
    for(int i = head[u];i;i = e[i].nxt)
    {
        int v = e[i].to;
        if(!dfn[v])
        {
            tarjan(v,fa);
            low[u] = min(low[u],low[v]);
            if(low[v] >= dfn[u] && u != fa)
                mrk[u] = true;
            if(u == fa)
                child++;
        }
        low[u] = min(low[u],dfn[v]);
    }
    if(child >= 2 && u == fa)
        mrk[u] = true;
}

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++)
        if(!dfn[i])
            tarjan(i,i);
    for(int i = 1;i <= n;i++)
        if(mrk[i])
            tot++;
    printf("%d\n",tot);
    for(int i = 1;i <= n;i++)
        if(mrk[i])
            printf("%d ",i);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/darlingroot/p/11221478.html