警示后人(if you WA #4 #6 #11)
查看原帖
警示后人(if you WA #4 #6 #11)
602372
Brilliant11001楼主2024/6/15 16:30

注意一个点可能在它的邻点回溯时被多次判为割点!

错误写法:

void tarjan(int u) {
    dfn[u] = low[u] = ++tim;
    int cnt = 0;
    for(int i = h[u]; ~i; i = ne[i]) {
        int j = e[i];
        if(!dfn[j]) {
            tarjan(j);
            low[u] = min(low[u], low[j]);
            if(low[j] >= dfn[u]) {
                ++cnt;
                if(u != root || cnt > 1) {
                    res++; //错误写法
                    is_cntv[u] = true;
                }
            }
        }
        else low[u] = min(low[u], dfn[j]);
    }
}

正确写法:

void tarjan(int u) {
    dfn[u] = low[u] = ++tim;
    int cnt = 0;
    for(int i = h[u]; ~i; i = ne[i]) {
        int j = e[i];
        if(!dfn[j]) {
            tarjan(j);
            low[u] = min(low[u], low[j]);
            if(low[j] >= dfn[u]) {
                ++cnt;
                if(u != root || cnt > 1) {
                    res = !is_cntv[u]; //可以这么写,也可以在主函数最后统计
                    is_cntv[u] = true;
                }
            }
        }
        else low[u] = min(low[u], dfn[j]);
    }
}

数据:

4 3
1 2
1 3
1 4
2024/6/15 16:30
加载中...