洛谷 p3388 【模板】割点(割顶)

题目链接

//priority_queue,greater >q;
#include 
#include
#include
#include
#include
#include
#include
using namespace std;
const int N=100010;
int n,m;
int low[N],dfn[N],head[N];
int sum,bridge,k;
int tot,p;
int uu[N];
struct node
{
    int v,next;
} s[N*3];
void init()
{
    tot=bridge=k=0;
    p=0;
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(uu,0,sizeof(uu));
    memset(head,-1,sizeof(head));
}
void add(int u,int v)
{
    s[tot].v=v;
    s[tot].next=head[u];
    head[u]=tot++;
}
void Tarjan(int u,int root)
{
    low[u]=dfn[u]=++k;
    int son=0;
    for(int i=head[u]; ~i; i=s[i].next)
    {
        int v=s[i].v;
        if(!dfn[v])
        {
            Tarjan(v,root);//注意为根节点
            low[u]=min(low[u],low[v]);
            if(low[v]>=dfn[u])//求割点
            {
                if(u==root)
                    son++;
                else
                    uu[u]++;
            }
        }
        else
            low[u]=min(low[u],dfn[v]);
    }
    if(u==root&&son>=2)
        uu[u]++;
}
int main()
{
    int u,v;
    init();
    scanf("%d%d",&n,&m);
    for(int i=1; i<=m; i++)
    {
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    for(int	i=1;i<=n;i++)
        if(!dfn[i])
        {
            Tarjan(i,i);
        }
    int	sum=0;
    for(int	i=1;i<=n;i++)
        if(uu[i])
            sum++;
    printf("%d\n",sum);
    for(int	i=1;i<=n;i++)
        if(uu[i])
            printf("%d ",i);
    return 0;
}

 

你可能感兴趣的:(【连通图/Tarjan】)