D16 Tarjan 割点

视频链接:https://www.bilibili.com/video/BV1QL4y1N7bC

// Luogu P3388 【模板】割点
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

const int N=20010;
int n,m,a,b;
vector<int> e[N]; 
int dfn[N],low[N],tot;
bool cut[N];
int root;

void tarjan(int x){
  dfn[x]=low[x]=++tot;
  int child=0;
  for(int y : e[x]){
    if(!dfn[y]){//若y尚未访问
      tarjan(y);
      low[x]=min(low[x],low[y]); 
      if(low[y]>=dfn[x]){
        child++;//子树个数
        if(x!=root||child>1)
          cut[x]=true;
      }
    }
    else//若y已经访问
      low[x]=min(low[x],dfn[y]);
  }
}
int main(){
  cin>>n>>m;
  while(m --){
    cin>>a>>b;
    e[a].push_back(b),
    e[b].push_back(a);
  }
  for(root=1; root<=n; root++)
    if(!dfn[root])tarjan(root);
  
  int ans=0;
  for(int i=1;i<=n;i++)
    if(cut[i]) ans++;
  printf("%d\n",ans);
  for(int i=1;i<=n;i++)
    if(cut[i]) printf("%d ",i);  
  return 0;
}

 

posted @ 2022-05-28 13:30  董晓  阅读(953)  评论(0编辑  收藏  举报