P3388 【模板】割点(割顶)

题面

https://www.luogu.org/problem/P3388

题解

#include<iostream>
#include<vector>
#include<cstdio>
#include<stack>
#include<cstring>
const int inf=987654321;
using namespace std;
int n,m,dfn[20050],low[20500],dad[20500],cloct,ans;
bool cut[20050];
vector<int> to[20050];

void tarjan(int x,int fa){
  int ch=0;
  dad[x]=fa;
  low[x]=dfn[x]=++cloct;
  int i,l=to[x].size();
  for (i=0;i<l;i++) if (to[x][i]!=fa) {
    if (!dfn[to[x][i]]) {
      ch++;
      tarjan(to[x][i],x);
      low[x]=min(low[x],low[to[x][i]]);
      if (low[to[x][i]]>=dfn[x] && !cut[x]) ans++,cut[x]=true;
    }
    else low[x]=min(dfn[to[x][i]],low[x]);
  }
  if (fa==-1) {
    if (ch>=2) {
      if (!cut[x]) ans++,cut[x]=true;
    } 
    if (ch==1 || ch==0) if (cut[x]) ans--,cut[x]=false;
  }
}

int main(){
  int i,u,v;
  scanf("%d %d",&n,&m);
  for (i=1;i<=m;i++) {
    scanf("%d %d",&u,&v);
    to[u].push_back(v);
    to[v].push_back(u);
  }
  cloct=0;
  for (i=1;i<=n;i++) if (!dfn[i]) {
    tarjan(i,-1);
  }
  cout<<ans<<endl;
  for (i=1;i<=n;i++) if (cut[i]) printf("%d ",i);
}
原文地址:https://www.cnblogs.com/shxnb666/p/11427421.html