[UOJ#67]新年的毒瘤:Tarjan

分析:

一个点满足题目要求当且仅当这个点不是割点并且这个点的度数为m-(n-2)。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>

inline int read(){
    int x=0;char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x;
}

const int MAXN=100005;
int n,m,ecnt,head[MAXN],deg[MAXN];
int dfn[MAXN],low[MAXN],tot;
int ans[MAXN],tot2;
bool cut[MAXN];
struct Edge{
    int to,nxt;
}e[MAXN<<1];

inline void add_edge(int bg,int ed){
    ecnt++;
    e[ecnt].to=ed;
    e[ecnt].nxt=head[bg];
    head[bg]=ecnt;
}

void tarjan(int x){
    dfn[x]=low[x]=++tot;
    int flag=0;
    for(int i=head[x];i;i=e[i].nxt){
        int ver=e[i].to;
        if(!dfn[ver]){
            tarjan(ver);
            low[x]=std::min(low[x],low[ver]);
            if(low[ver]>=dfn[x]){
                flag++;
                if(x!=1||flag>1) cut[x]=1;
            }
        }
        else low[x]=std::min(low[x],dfn[ver]);
    }
}

int main(){
    n=read(),m=read();
    for(int i=1;i<=m;i++){
        int u=read(),v=read();
        add_edge(u,v);
        add_edge(v,u);
        deg[u]++;
        deg[v]++;
    }
    tarjan(1);
    for(int i=1;i<=n;i++)
        if(!cut[i]&&deg[i]==m-(n-2)) ans[++tot2]=i;
    printf("%d\n",tot2);
    for(int i=1;i<=tot2;i++)
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ErkkiErkko/p/9703646.html
67