• Tarjan算法求图的割点和桥-模版


    2020-09-26 15:51:22

    一、定义

    割点:无向连通图中,某点和其连接的边去除后,图不再连通

    桥:无向连通图中,某边去除后,图不再连通

    二、Tarjan算法

    Tarjan算法可以在一次dfs中得到所有的割点和割边。

    time: 时间戳

    dfn[]: dfs第一次遍历到的时间戳

    low[]: 通过子节点能够访问到的最小时间戳

    fa[]: 记录父亲节点

    • 割点

    • 总结

    三、模版

    LC. 1568

        int time = 1;
        int[] dfn = new int[1000];
        int[] low = new int[1000];
        int[] fa = new int[1000];
        Set<Integer> set = new HashSet<>();
        int bridge = 0;
        int[][] dirs = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
        
        int m;
        int n;
        
        
        public int minDays(int[][] grid) {
            Arrays.fill(fa, -1);
            m = grid.length;
            n = grid[0].length;
            int cnt = 0;
            int total = 0;
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    if (grid[i][j] == 0) continue;
                    total += 1;
                    int node = i * n + j;
                    if (dfn[node] == 0) {
                        dfs(grid, i, j);
                        cnt += 1;
                    }
                }
            }
            if (cnt == 0 || cnt > 1) return 0;
            if (set.size() > 0 || total == 1) return 1;
            else return 2;
        }
        
        private void dfs(int[][] grid, int i, int j) {
            int node = i * n + j;
            dfn[node] = time;
            low[node] = time;
            time += 1;
            int child = 0;
            for (int[] dir : dirs) {
                int ni = i + dir[0];
                int nj = j + dir[1];
                if (ni < 0 || ni >= m || nj < 0 || nj >= n) continue;
                if (grid[ni][nj] == 1) {
                    int next = ni * n + nj;
                    if (dfn[next] == 0) {
                        child += 1;
                        fa[next] = node;
                        dfs(grid, ni, nj);
                        if (fa[node] == -1 && child >= 2) {
                            set.add(node);
                        }
                        if (fa[node] != -1 && low[next] >= dfn[node]) {
                            set.add(node);
                        }
                        if (low[next] > dfn[node]) {
                            bridge += 1;
                        }
                        low[node] = Math.min(low[node], low[next]);
                    }
                    else if (next != fa[node]) {
                        low[node] = Math.min(low[node], low[next]);
                    }
                }
            }
        }
    

      

  • 相关阅读:
    建筑名称解释
    delphi 文件查找
    bat如何批量删除指定部分文件夹名的文件夹
    在 DELPHI 中 procedure 型变量与 method 型变量的区别
    Spearman Rank(斯皮尔曼等级)相关系数
    机器学习的MLE和MAP:最大似然估计和最大后验估计
    error “Device supports x86, but APK only supports armeabi-v7a”
    windows 安装ninja
    Gradle语法基础解析
    executing external native build for cmake
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/13735387.html
Copyright © 2020-2023  润新知