割点

割点

割点是如果删除这个点, 连通块 + 1 的点就是割点。

可以发现,在 DFS 树上, 如果一个点的儿子不能通过一些非树边到达它的父亲, 如果把它删除, 这个儿子将会和他的父亲不连通。

#include<bits/stdc++.h>

using namespace std;

const int N = 2e5 + 5;

int low[N], cnt, dfn[N], n, m, u, v;

struct Edge{
  int v, w;
};

vector<Edge>g[N];

vector<int>e;

void dfs(int x, int f){
  int son = 0, flag = 0;
  dfn[x] = low[x] = ++cnt;
  for(auto [v, w] : g[x]){
    if(!dfn[v]){
      dfs(v, x);
      low[x] = min(low[x], low[v]);
      son++;
      if(f && low[v] >= dfn[x] || !f && son > 1){
        flag = 1;
      }
    }
    else if(v != f){
      low[x] = min(low[x], dfn[v]);
    }
  }
  if(flag){
    e.push_back(x);
  }
}

int main(){
  cin >> n >> m;
  for(int i = 1; i <= m; ++i){
    cin >> u >> v;
    g[u].push_back({v, i});
    g[v].push_back({u, i});
  }
  for(int i = 1; i <= n; ++i){
    if(!dfn[i]){
      dfs(i, 0);
    }
  }
  cout << e.size() << '\n';
  sort(e.begin(), e.end());
  for(auto x : e){
    cout << x << ' ';
  }
  return 0;
}

细节 : 根节点只有有超过一个儿子就是割点。

posted @ 2024-04-09 16:16  liuyichen  阅读(6)  评论(0编辑  收藏  举报