图论17-有向图的强联通分量-Kosaraju算法

文章目录

  • [1 概念](#1 概念)
  • [2 Kosaraju算法](#2 Kosaraju算法)
    • [2.1 在图类中设计反图](#2.1 在图类中设计反图)
    • [2.2 强连通分量的判断和普通联通分量的区别](#2.2 强连通分量的判断和普通联通分量的区别)
    • [2.3 代码实现](#2.3 代码实现)

1 概念


2 Kosaraju算法

对原图的反图进行DFS的后序遍历。

2.1 在图类中设计反图

c 复制代码
// 重写图的构造函数
    public Graph(TreeSet<Integer>[] adj, boolean directed){

        this.adj = adj;
        this.directed = directed;
        this.V = adj.length;
        this.E = 0;

        indegrees = new int[V];
        outdegrees = new int[V];
        for(int v = 0; v < V; v ++)
            for(int w: adj[v]){
                outdegrees[v] ++;
                indegrees[w] ++;
                this.E ++;
            }

        if(!directed) this.E /= 2;
    }

// 求反图,并且new一个图对象,参数为TreeSet
    public Graph reverseGraph(){

        TreeSet<Integer>[] rAdj = new TreeSet[V];
        for(int i = 0; i < V; i ++)
            rAdj[i] = new TreeSet<Integer>();

        for(int v = 0; v < V; v ++)
            for(int w : adj(v))
                rAdj[w].add(v);

        return new Graph(rAdj, directed);
    }

2.2 强连通分量的判断和普通联通分量的区别

强联通分量是环,意味着在DFS过程中一定是公用相同的联通分量序号。

当这个环遍历从环尾开始返回并记录ccid的时候,DFS自由返回到环, 索引指向下一个未被访问过的环外的节点,此时联通分量序号+1。 由于图是反过来的。

单步调试一下更容易理解。

2.3 代码实现

顶点:注意这里遍历的顺序是反过来的图。

并且,对翻转过来的图进行DFS后序遍历。

cpp 复制代码
        GraphDFS dfs = new GraphDFS(G.reverseGraph());

        ArrayList<Integer> order = new ArrayList<>();
        for(int v: dfs.post())
            order.add(v);

        Collections.reverse(order);

        for(int v: order) //注意这里遍历的顺序是反过来的图
            if(visited[v] == -1){
                dfs(v, scccount);
                scccount ++;
            }

但是在DFS的时候,判断邻边用的是原来的邻接列表。

c 复制代码
    private void dfs(int v, int sccid){

        visited[v] = sccid;
        for(int w: G.adj(v))
            if(visited[w] == -1)
                dfs(w, sccid);
    }
相关推荐
其实防守也摸鱼6 小时前
个人学习 Pwn 思路:从基础到漏洞利用的进阶路径
大数据·前端·人工智能·chrome·算法·安全·网络安全
Nuanyt6 小时前
LeetCode Hot 100 链表专题(五)· 2 题(Java)
java·算法·leetcode·链表
w_zero_one9 小时前
递归算法(一)
java·开发语言·算法
风影同志7832411 小时前
20 个比特能装下多少行情?——实测拆解 Kronos 的 K 线分词器
算法
写的都是BUG11 小时前
APK 里的钥匙,一直就放在门口:聊聊加固真正该做什么
前端·算法
地平线开发者12 小时前
CLIP 的零样本分类:一组文本如何变成图像分类器?
算法
京东云开发者12 小时前
从“会生成”到“能生产”:萤火虫 AIGC 平台的 AI Infra 实践
算法·aigc·产品
youshi666812 小时前
PID——算法改进
算法
一只不想敲代码的程序猿14 小时前
如何更高效地拆解问题?
算法