洛谷 p3388 【模板】割點(割頂)

題目鏈接

//priority_queue<int,vector<int>,greater<int> >q;
#include <iostream>
#include<vector>
#include<stack>
#include<queue>
#include<stdio.h>
#include<string.h>
#include<algorithm>
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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章