代码改变世界

【模板】割点(割顶)

2019-04-07 23:20  一只弱鸡丶  阅读(206)  评论(0编辑  收藏  举报

题目链接:https://www.luogu.org/

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define P pair<int,int>
const int N=1e6+10;
void read(int &a)
{
    a=0;
    int d=1;
    char ch;
    while(ch=getchar(),ch>'9'||ch<'0')
        if(ch=='-')
            d=-1;
    a=ch-'0';
    while(ch=getchar(),ch>='0'&&ch<='9')
        a=a*10+ch-'0';
    a*=d;
}
void write(int x)
{
    if(x<0)
        putchar(45),x=-x;
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
}
int head[N],tot,low[N],dfn[N],num,ans;
bool cut[N];
struct note
{
    int u,v,next;
}edge[N];
void add(int u,int v)
{
    edge[++tot].next=head[u];
    edge[tot].v=v;
    head[u]=tot;
}
void dfs(int u,int fa)
{
    int child=0;
    dfn[u]=low[u]=++num;
    for(re int i=head[u];i;i=edge[i].next)
    {
        int v=edge[i].v;
        if(!dfn[v])
        {
            if(u==fa)
                child++;
            dfs(v,fa);
            low[u]=min(low[u],low[v]);///更新这个点到其他点最小的时间戳
            if(u!=fa&&low[v]>=dfn[u])///除了第一个节点外满足  low[v]>=dfn[u]都是割点
                cut[u]=1;
        }
        low[u]=min(low[u],dfn[v]);///更新这个点到其他点最小的时间戳
    }
    if(child>=2)
        cut[u]=1;
}
int main()
{
    int n,m;
    read(n);
    read(m);
    for(re int i=0;i<m;i++)
    {
        int a,b;
        read(a);
        read(b);
        add(a,b);
        add(b,a);
    }
    for(re int i=1;i<=n;i++)
    {
        if(!dfn[i])
            dfs(i,i);
    }
    for(re int i=1;i<=n;i++)
        if(cut[i])
            ans++;
    write(ans);
    putchar('\n');
    for(re int i=1;i<=n;i++)
        if(cut[i])
            write(i),putchar(' ');
    return 0;
}

 

problemnew/show/P3388