洛谷P3388 缩点

Tarjan入门题。
Code:

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
#define ll long long
#define maxn 100001
using namespace std;
struct Edge{
    int nxt,to;
}edge[maxn*2];
int num_edge,head[maxn],dfn[maxn],low[maxn],n,m,cnt[maxn],tot,cut;
stack<int> s;
inline void addedge(int from,int to){
    edge[++num_edge].nxt=head[from];
    edge[num_edge].to=to;
    head[from]=num_edge;
}
void tarjan(int x,int fa){
    dfn[x]=low[x]=++cut;
    int child=0;
  //  s.push(x);
    for(int i=head[x];i;i=edge[i].nxt){
        int y=edge[i].to;
        if(!dfn[y]){
            tarjan(y,fa);
            low[x]=min(low[x],low[y]);
            if(low[y]>=dfn[x]&&x!=fa){
                cnt[x]=1;
            }
            if(x==fa){
                child++;
            }
        }
      //  else if(!sccnum[y]){
           low[x]=min(dfn[y],low[x]);
           
           }
           if(child>=2&&x==fa){
                   cnt[x]=1;
      //  }
    }
  //  if(low[x]==dfn[x]){
   //     scc_cnt++;
   //     for(;;){
   //         //num[vscc_cnt]++;
    //        int y=s.top();
   //         tot[scc_cnt]+=a[y];
    //        s.pop();
    //        sccnum[y]=scc_cnt;
    //        if(y==x) break;
    //    }
   // }
}
int main(){
//    memset(head,0,sizeof(head));
//    memset(dfn,0,sizeof(dfn));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        addedge(x,y);
        addedge(y,x);
    }
    for(int i=1;i<=n;i++){
        if(dfn[i]==0){
            tarjan(i,i);
        }
    }
    for(int i=1;i<=n;i++){
        if(cnt[i]){
            tot++;
        }
    //    cout<<cnt[i]<<" ";
    }
    printf("%d
",tot);
    for(int i=1;i<=n;i++){
        if(cnt[i]){
            printf("%d ",i);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/kenlig/p/9822603.html