【模板】tarjan割点

 

注意有两个变量

 

now是判断x是不是根,并不是父节点

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100005;
struct edge{
    int to, next;
}e[maxn << 1];
int head[maxn], cnt;
int n, m, a, b;
int low[maxn], dfn[maxn], ch, cut[maxn], ans, num;

void add(int u, int v)
{
    e[++cnt].to = v;
    e[cnt].next = head[u];
    head[u] = cnt;
}

void tarjan(int x, int now)
{
    dfn[x] = low[x] = ++num;
    ch = 0;
    for(int i = head[x]; i; i = e[i].next)
    {
        int y = e[i].to;
        if(!dfn[y])
        {
            tarjan(y, x);
            low[x] = min(low[x], low[y]);
            if(low[y] >= dfn[x] && now != -1)
                cut[x] = 1;
        }
        else if(x != now) low[x] = min(low[x], dfn[y]);
    }
    if(now == -1 && ch > 1) cut[x] = 1;    
}

int main()
{
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        scanf("%d%d", &a, &b);
        add(a, b); add(b, a);
    }
    for(int i = 1; i <= n; i++)
        if(!dfn[i]) tarjan(i, -1);
    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 @ 2019-11-13 21:53  ATKevin  阅读(115)  评论(0)    收藏  举报