标程:【模板】割点(割顶)

Andrewzdm 2020-03-31 20:02:09 2020-04-01 21:53:46 14 返回题目

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 1e5 + 5, maxm = 5e5 + 5;
int n, m, ans;
int h[maxn], en;
struct Edge {
    int u;
    int v;
    int next;
};
Edge e[2 * maxm];
int dfn[maxn], low[maxn], order;
bool cut[maxn];

void addedge(int u, int v) {
    en++;
    e[en].u = u;
    e[en].v = v;
    e[en].next = h[u];
    h[u] = en;
    return;
}

void dfs(int x, int fa) {
    dfn[x] = low[x] = ++order;
    int cnt = 0;
    for (int i = h[x]; i != 0; i = e[i].next) {
        int v = e[i].v;
        if (v == fa)
            continue;
        if (dfn[v] == 0) {
            dfs(v, x);
            low[x] = min(low[x], low[v]);
            cnt++;
            if (low[v] >= dfn[x] && fa != 0)
                cut[x] = true;
        } else
            low[x] = min(low[x], dfn[v]);
    }
    if (fa == 0 && cnt > 1)
        cut[x] = true;
    return;
}

void tarjan() {
    for (int i = 1; i <= n; i++)
        if (dfn[i] == 0)
            dfs(i, 0);
    return;
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        addedge(u, v);
        addedge(v, u);
    }
    tarjan();
    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);
    printf("\n");
    return 0;
}
{{ vote && vote.total.up }}

共 1 条回复

huayucaiji

stO zdm Orz