Luogu P3388 [template] cut point (cut top) (tarjan cut point)

Keywords: C++

Background of topic

Cut point

Title Description

In this paper, we give an undirected graph with n points and m edges, and find the cut points of the graph.

I / O format

Input format:

 

Input n,m in the first line

In the following m lines, enter x for each line. Y means there is an edge between X and y

 

Output format:

 

Number of output cut points in the first line

The second line outputs nodes from small to large according to the node number, separated by spaces

 

Example of input and output

Input example ා 1:copy
6 7
1 2
1 3
1 4
2 5
3 5
4 5
5 6
Output example:copy
1 
5

Explain

n. M is 100000

tarjan graph is not necessarily connected!!!

 

tarjan's cut point,

If $low [v] >

Then $u $must be able to separate $v $from the previous point

The root node needs special judgment. Only when there are more than two children is the cut point

 

// luogu-judger-enable-o2
#include<cstdio>
#include<cstring>
#include<algorithm>
#define getchar() (S == T && (T = (S = BB) + fread(BB, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
char BB[1 << 15], *S = BB, *T = BB;
using namespace std;
const int MAXN=1e6+10;
inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct node
{
    int u,v,nxt;
}edge[MAXN];
int head[MAXN],num=1;
inline void AddEdge(int x,int y)
{
    edge[num].u=x;
    edge[num].v=y;
    edge[num].nxt=head[x];
    head[x]=num++;
}
int dfn[MAXN],low[MAXN],cut[MAXN],tot=0;
int tarjan(int now,int fa)
{
    int ch=0;
    dfn[now]=low[now]=++tot;
    for(int i=head[now];i!=-1;i=edge[i].nxt)
    {
        if(!dfn[edge[i].v])
        {
            tarjan(edge[i].v,fa);
            low[now]=min(low[now],low[edge[i].v]);
            if(low[edge[i].v]>=dfn[now]&&now!=fa) cut[now]=1;
            if(now==fa) ch++; 
        }
        low[now]=min(low[now],dfn[edge[i].v]);
    }
    if(now==fa&&ch>=2) cut[now]=1;
}
int main()
{
    #ifdef WIN32
    freopen("a.in","r",stdin);
    #else
    #endif
    memset(head,-1,sizeof(head));
    int N=read(),M=read();
    for(int i=1;i<=M;i++)
    {
        int x=read(),y=read();
        AddEdge(x,y);
        AddEdge(y,x);
    }
    for(int i=1;i<=N;i++)
        if(!dfn[i])
            tarjan(i,i);
    int ans=0;
    for(int i=1;i<=N;i++)
        if(cut[i]) ans++;
    printf("%d\n",ans);
    for(int i=1;i<=N;i++)
        if(cut[i]) printf("%d ",i);
    return 0;
}

Posted by sonofsam on Sun, 05 Apr 2020 19:00:56 -0700