图的割边 Critical Connections in a Network

2019-10-05 23:40:13

问题描述:

 

问题求解:

本题首次出现在Contest 154,是一条模版题,是一条经典的求割边的问题,该问题有Tarjan算法,可以在O(n + e)的时间复杂度求解。

Tarjan算法的核心思路是维护两个数组discovery[],low[]。disc[]数组里存放访问节点的时间戳,low[]数组里存放与节点邻接的(不包含父节点)最小时间戳的节点。

每次比较父节点和子节点,如果子节点没有访问到时间戳小的节点,那么这两个节点之间必然有一条割边。

    int timestamp = 1;
    public List<List<Integer>> criticalConnections(int n, List<List<Integer>> connections) {
        int[] disc = new int[n];
        int[] low = new int[n];
        List<List<Integer>> res = new ArrayList<>();
        List<Integer>[] graph = new ArrayList[n];
        for (int i = 0; i < n; i++) graph[i] = new ArrayList<>();
        for (int i = 0; i < connections.size(); i++) {
            int u = connections.get(i).get(0);
            int v = connections.get(i).get(1);
            graph[u].add(v);
            graph[v].add(u);
        }
        Arrays.fill(disc, -1);
        helper(graph, 0, disc, low, -1, res);
        return res;
    }
    
    private void helper(List<Integer>[] graph, int node, int[] disc, int[] low, int prev, List<List<Integer>> res) {
        disc[node] = timestamp;
        low[node] = timestamp;
        timestamp += 1;
        for (int u : graph[node]) {
            if (u == prev) continue;
            if (disc[u] == -1) {
                helper(graph, u, disc, low, node, res);
                if (low[u] > disc[node]) {
                    res.add(Arrays.asList(u, node));
                }
            }
            low[node] = Math.min(low[node], low[u]);   
        }
    

猜你喜欢

转载自www.cnblogs.com/hyserendipity/p/11626175.html