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]);
                }
            }
        }
    }

  

 

posted @ 2020-09-26 16:03  hyserendipity  阅读(267)  评论(0编辑  收藏  举报