• T103492 【模板】点双连通分量


    题目传送门

    实现代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 10, M = 2 * N;
    
    int dfn[N], low[N];
    int n, m;
    int timestamp, root;
    int stk[N], top; // tarjan用的栈
    vector<int> dcc[N];
    int dcc_cnt;
    
    //邻接表
    int e[M],
        h[N], idx, ne[M];
    void add(int a, int b) {
        e[idx] = b, ne[idx] = h[a], h[a] = idx++;
    }
    //点双连通分量 模板
    void tarjan(int u) {
        dfn[u] = low[u] = ++timestamp;   //分配时间戳
        stk[++top] = u;                  // u入栈
        if (u == root && h[u] == -1) {   // 根,而且没有出边,孤立点
            dcc[++dcc_cnt].push_back(u); // 分量数++
            return;
        }
        for (int i = h[u]; ~i; i = ne[i]) { //枚举u的每条边
            int j = e[i];
            if (!dfn[j]) {                    //如果j没有被走过
                tarjan(j);                    // dfs
                low[u] = min(low[u], low[j]); //用儿子的low[j]尝试更新low[u]
                if (low[j] >= dfn[u]) {       //如果u是割点
                    dcc_cnt++;                //连通块增加
                    int y;                    //利用栈,维护此连通块中所有的点
                    do {
                        y = stk[top--];
                        dcc[dcc_cnt].push_back(y);
                    } while (y != j);
                    dcc[dcc_cnt].push_back(u); // u是割点,也必须属于其它连通块,不能用了拉倒,需要再次入栈
                }
            } else
                low[u] = min(low[u], dfn[j]);
        }
    }
    
    int main() {
        memset(h, -1, sizeof h);
        cin >> n >> m;
        for (int i = 0; i < m; i++) {
            int a, b;
            cin >> a >> b;
            add(a, b), add(b, a);
        }
        //给定一个n个点m条边的无向图,求该图中的所有点双连通分量(v-dcc)
        for (root = 1; root <= n; root++) //每个点做为根结点进行枚举
            if (!dfn[root]) tarjan(root);
    
        for (int i = 1; i <= dcc_cnt; i++) {        //枚举每个双连通分量
            for (int j = 0; j < dcc[i].size(); j++) //输出双连通分量中的点有哪些
                printf("%d ", dcc[i][j]);
            puts("");
        }
        return 0;
    }
    
  • 相关阅读:
    .Net工具 SocanCode代码生成器
    .net开发中两个“属性”引起的歧异
    读取Excel文件时出现null的解决方法
    Spring中XML配置的12个技巧
    oracle中的NVL,NVL2,NULLIF,COALESCE几个通用函数
    VB6各数据类型序列化和反序列化
    Oracle分页查询语句(四)
    ASP.NET知识库
    你知道.NET框架下的自动内存管理吗?
    构建支持 Ajax 的自动完成和级联式下拉控件
  • 原文地址:https://www.cnblogs.com/littlehb/p/16099011.html
Copyright © 2020-2023  润新知