割点-模板

洛谷割点模板:https://www.luogu.org/problemnew/show/P3388

 

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdio>
#include <vector>

using namespace std;
const int maxn = 100009;
vector<int> q, mp[maxn];
int cnt, root, ind;
int num[maxn], low[maxn], used[maxn];
void dfs(int cur, int father) {
    ind++;
    num[cur] = low[cur] = ind;
    int child = 0;
    for (int i = 0; i < mp[cur].size(); i++) {
        int to = mp[cur][i];
        if (num[to] == 0) {
            child++;
            dfs(to, cur);
            low[cur] = min(low[cur], low[to]);
            //特别注意!有可能在Tarjian时x的儿子有多个!
            //更新时且都符合条件!故ans被累加多次!注意判重!
            if (cur != root && low[to] >= num[cur])
                if (used[cur] == 0) used[cur] = 1, cnt++, q.push_back(cur);
            if (root == cur && child == 2)
                if (used[cur] == 0) used[cur] = 1, cnt++, q.push_back(cur);
        } else if (to != father) {
            low[cur] = min(low[cur], num[to]);
        }
    }
}
int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        mp[u].push_back(v);
        mp[v].push_back(u);
    }
    for (int i = 1; i <= n; i++) {
        if (num[i] == 0) //由于所有点不是全部连通的;
            ind = 0, root = i, dfs(root, 0);
    }
    sort(q.begin(), q.end());
    printf("%d\n", cnt);
    for (int i = 0; i < q.size(); i++) {
        printf("%d ", q[i]);
    }
    return 0;
}
View Code

 

posted @ 2018-03-06 22:43  ckxkexing  阅读(101)  评论(0编辑  收藏  举报