UOJ#67新年的毒瘤(Tarjan)

Posted cjyyb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UOJ#67新年的毒瘤(Tarjan)相关的知识,希望对你有一定的参考价值。

【UOJ#67】新年的毒瘤(Tarjan)

题面

UOJ

题解

一棵(n)个节点的树显然有(n-1)条边,在本题中意味着删去一个点之后还剩下(n-2)条边。那么找到所有度数为(m-(n-2))的点就好了。但是因为是一棵树,所以联通,所以割点不是答案。

#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
#define MAX 100100
inline int read()
{
    int x=0;bool t=false;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=true,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return t?-x:x;
}
struct Line{int v,next;}e[MAX<<1];
int h[MAX],cnt=1,dg[MAX];
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;dg[u]++;}
int n,m,dfn[MAX],low[MAX],tim,S[MAX],top,rt,son;
bool cut[MAX];
void Tarjan(int u,int ff)
{
    dfn[u]=low[u]=++tim;
    for(int i=h[u];i;i=e[i].next)
    {
        int v=e[i].v;if(v==ff)continue;
        if(!dfn[v])
        {
            Tarjan(v,u);
            low[u]=min(low[u],low[v]);
            if(low[v]>=dfn[u])
            {
                if(u^rt)cut[u]=true;
                else ++son;
            }
        }
        else low[u]=min(low[u],dfn[v]);
    }
    if(u==rt&&son>1)cut[u]=true;
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=m;++i)
    {
        int u=read(),v=read();
        Add(u,v);Add(v,u);
    }
    for(int i=1;i<=n;++i)if(!dfn[i])Tarjan(rt=i,son=0);
    for(int i=1;i<=n;++i)if(!cut[i]&&(m-dg[i]==n-2))S[++top]=i;
    printf("%d
",top);
    for(int i=1;i<=top;++i)printf("%d ",S[i]);
    puts("");return 0;
}

以上是关于UOJ#67新年的毒瘤(Tarjan)的主要内容,如果未能解决你的问题,请参考以下文章

UOJ67 新年的毒瘤

UOJ #67. 新年的毒瘤

[UOJ#351]新年的叶子

UOJ #146. NOIP2015信息传递 连通分量 tarjan模板题

UOJ#351. 新年的叶子 概率期望

UOJ#460. 新年的拯救计划 构造