{"id":19226674,"url":"https://github.com/huichuanli/play-with-graph-algorithme","last_synced_at":"2026-04-02T02:00:42.266Z","repository":{"id":127179617,"uuid":"198235545","full_name":"HuichuanLI/play-with-graph-algorithme","owner":"HuichuanLI","description":"python实现的初级图论算法库:环检测问题,桥和割点,最小生成树,最短路径,欧拉路径,哈密尔顿路径,拓扑排序，最大流问题，匹配问题(匈牙利算法)","archived":false,"fork":false,"pushed_at":"2021-09-16T16:08:37.000Z","size":16561,"stargazers_count":46,"open_issues_count":0,"forks_count":9,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-21T00:35:00.001Z","etag":null,"topics":["graph-algorithms","graph-theory","java","python"],"latest_commit_sha":null,"homepage":"","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HuichuanLI.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-07-22T14:05:50.000Z","updated_at":"2025-03-31T14:13:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"a079b861-3c6b-45bd-824a-cb6253cf1f10","html_url":"https://github.com/HuichuanLI/play-with-graph-algorithme","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/HuichuanLI/play-with-graph-algorithme","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HuichuanLI%2Fplay-with-graph-algorithme","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HuichuanLI%2Fplay-with-graph-algorithme/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HuichuanLI%2Fplay-with-graph-algorithme/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HuichuanLI%2Fplay-with-graph-algorithme/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HuichuanLI","download_url":"https://codeload.github.com/HuichuanLI/play-with-graph-algorithme/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HuichuanLI%2Fplay-with-graph-algorithme/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31294356,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T01:43:37.129Z","status":"online","status_checked_at":"2026-04-02T02:00:08.535Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graph-algorithms","graph-theory","java","python"],"created_at":"2024-11-09T15:19:40.713Z","updated_at":"2026-04-02T02:00:42.253Z","avatar_url":"https://github.com/HuichuanLI.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# play-with-graph 玩转图论算法\n##  第一个问题关于图的表示\n![photo](src/photo/1.png)\n\n# 图的表示\n\t\n![photo](src/photo/2.png)\n## 社交网路\n![photo](src/photo/3.png)\n\n\n![photo](src/photo/4.png)\n\n## 图的分类算法\n无向无权图 \n无向有权图 \n有向无权图 \n有向有权图\n\n\n# 图的基本概念\n## \t无向无权图\n\n![photo](src/photo/5.png)\n\n![photo](src/photo/6.png)\n\n没有自环边，没有平行边， 称为简单图\n\n![photo](src/photo/7.png)\n\n### 联通分量 \n\t一个图的所有节占不一定全部相连 \n\t一个图可能有多个联通分量\n\n\n###  无环图 \n\t树是一种无环图。无环图不一定是树\n\t联通的无环图就是树\n\n\n![photo](src/photo/8.png)\n\n## 包含所有顶占边数V·1， 一定是联通图的生成树吗？\n\n![photo](src/photo/9.png)\n\n\n\t不是！\n\n###  一个图一定有生成树吗？\n\n\t没有\n\n![photo](src/photo/10.png)\n\n### 一个顶点的度 \n\n![photo](src/photo/11.png)\n\n##  邻接矩阵\n\n![photo](src/photo/12.png)\n\n[实现code](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/AdjMatrix.java)\n\n复杂度\n\n![photo](src/photo/13.png)\n\n\t可以优化空间复杂度 O(V2)\n\t如果一个图有3000个节点\n\t空间：5999vs3000^2约1000万 \n\t求相邻顶点．degree(v)vs3000\n\n## 稀疏图和稠密图\n\n![photo](src/photo/14.png)\n![photo](src/photo/15.png)\n稠密图\n![photo](src/photo/16.png)\n平均每个度比较最大的度\n## 邻接表\n![photo](src/photo/17.png)\n[实现code](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/AdjList.java)\n\n## 空间复杂度\n\t空间复杂度，O(V+E)\n\t如果是 树的话 O（2E+1）= O(E)\n\t如果是完全图的话 O（v*(V-1)/2 + E）= O(E)\n\t但是 不能写O(E) 如果不联通\n\n## 时间复杂度：\n建图：O(E*V)  和邻接矩阵 相差了v\n\t\n看两点是否相邻 ：O(degree(v))  原来是O(1)\n\n求一个点的相邻节点 : O(degree(v)) 只需要遍历所有相邻节点个数\n\t\n快速查重 \n\t\n快速查看两点是否相邻\n\t\n不要使用链表 \n\t\nhash 表 HashSet O(1)\n\t\n红黑树 TreeSet O(logv)\n\t\n因为红黑树 考虑到元素之间的顺序性，为了保证TreeSet，为了使得结果相对可视化。\n\n红黑树相对于hash表内存空间相对于少。\n\n时间复杂度虽然会增加 o(1) \u003c o(logn) \u003c o(n) 比如 100w 1\u003c 20 \u003c 1000000\n\n算法优化 使用红黑树而对于java使用[TreeSet](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/AdjSet.java)\n\n\n## 算法复杂度\n![photo](src/photo/18.png)\n\n我们可以看出来邻接表，在其他方面都是优于其他的表示方法。\n\n所以我们接下来，都是使用邻接表。基于TreeSet。\n\n\n# 图的遍历\n\n\t\n图是一种数据结构 每种数据结构，都必须有“遍历\"的方式\n\n比如树的遍历: \n\n![photo](src/photo/19.png)\n\n很多算法本质就是遍历，其实看算法中是否有关。\n\n其实80%的面试问题都可以解决了。\n\n图其实就是比树要解决，重复遍历的问题。每次需要记录，那个节点被遍历。\n\n图论不考虑非递归算法。\n\n其实图论算法都是从树的遍历的引申，其实很像，其实底层实现很想。\n\n![photo](src/photo/20.png)\n\n其实对应n叉树，很像。\n\n代码[DFS](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/GraphDfs.java)\n\n\n回归二叉树的遍历\n\n![photo](src/photo/21.png)\n\n类似的 我们可以推导后续遍历\n\n![photo](src/photo/22.png)        \n\n\n\n复杂度 O（V+E）\n\n\n关于优先遍历的应用：二分图\n\n\n非递归的手法，深度优先遍历，其实很难，邻接矩阵的深度优先遍历\n\n邻接表的深度优先遍历，其实一样。无非就是改变接口，但是注意时间复杂度: O(V^2)\n\n因为这个过程，我们依然要遍历所有顶点的所有邻边。但是遍历一个顶点的所有邻边的时候，要遍历所有的顶点，复杂度是O(V)的，而非O(degree(v))的。\n\n因此，整体，遍历所有顶点的所有邻边，需要的时间复杂度是O(V^2)的。\n\n代码实现 : [ADJDFS](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/adjMatrixDFS.java)\n\n使用图的接口 : [Interface](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/GraphInterface.java)\n\n\n大家可以看到，我们写的DFS算法类，其实封装的非常好，只需要简单的将类中传入的所有Graph类型（对应第二章中AdjSet的实现），修改为AdjMatrix，就可以完全正确地执行针对链接矩阵AdjMatrix的深度优先遍历了。\n\n\n关于图的非递归的深度优先遍历\n\n首先先复习一下，使用栈，树的非递归的实现, 如 Leetcode 144 \n\n    // 深度优先遍历的非递归实现，需要使用一个栈\n    Stack\u0026lt;TreeNode\u0026gt; stack = new Stack\u0026lt;TreeNode\u0026gt;();\n    // 栈中首先压入根节点root\n    stack.push(root);\n    \n    // 只要栈不为空，说明还有未被遍历的节点\n    while(!stack.empty()){\n\n    // 遍历栈顶元素\n    TreeNode curNode = stack.pop();\n    // 在这个例子中，遍历的方式是将该节点的值放入一个线性表res中\n    res.add(curNode.val); \n\n    // 之后，把当前节点的左右孩子压入栈中，等待后续的遍历\n    if(curNode.right != null)\n        stack.push(curNode.right);\n    if(curNode.left != null)\n        stack.push(curNode.left);\n    }\n    \n那么对于这种来其实一样。\n\n实现代码：[code](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/GraphDFSnr.java)\n\n注意这里的结果和以前的不一样\n\n递归 ：\n    [0, 1, 3, 2, 6, 5, 4 ] \n\n非递归 ： \n    [0, 2, 1, 3, 5, 4, 6]\n\n其实很简单。因为非递归的过程，我们是将一个顶点的相邻顶点压入栈中，取出的时候，是反向的；而递归没有这个问题，我们会按照adj(v)返回的列表的顺序，依次做深度优先遍历。+在这里，对此有疑问的同学，强烈建议实际对这两个程序进行一下单步跟踪，仔细理解一下，为什么会产生不一样的结果？通过但不跟踪，了解算法的每一步在做什么，每一步变量都发生了怎样的变化，怎样一点一点得到了最终的结果，这可是学习算法的重要方式哦。很多时候，顿悟，就发生在这个过程中：）\n\n当然了，其实，这两个结果，都是图的深度优先遍历的结果。\n\n\n\n# 图的优先遍历的应用\n\n## 无向图的联通分量\n\n![photo](src/photo/23.png) \n\n代码：可以通过深度优先遍历，查看哪些是联通分量\n\n[code](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/CC.java)\n\n\n## 路径问题 \n\n两点在同一个联通分量， 意味着两点间有路径\n\n\n路径怎么求 \n\n![photo](src/photo/24.png) \n\n对应这种问题，我们向对来说，只能求从0到那个节点有路径，从某个点出发，到任意位置的路径，单源路径。\n\n[SingleSourcePath](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/SingleSourcePath.java)\n\n那么我们现在只是解决了单源问题，但是没解决多源问题，所以如何解决所有点路径的问题。\n\n我们其实全部遍历点就好了，创建一个SingleSourcePath 数组\n\n\n[AllPairsPath](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/AllPairsPath.java)\n\n对于递归提前结束，没必要全部都遍历\n\n[Path](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/Path.java)\n\n\n## 检测无向图中的环\n\n[CycleDetection](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/CycleDetection.java)\n\n在这一小节，我们实现了无向图的环检测代码。那么现在能不能实现一个简单的算法逻辑，来判断，给定的一张图，是否是一棵树?\n\n必须保证图是联通的，同时没有环，才能说明这张图是一棵树。\n\n在这一章，我们已经封装了求解图的连通分量的 CC 类，和环检测 CycleDetection 类,其实就可以判断一个图是不是树。\n\n\n## 二分图检测\n\n![photo](src/photo/25.png) \n\n\n![photo](src/photo/26.png) \n\n左右两边是一样的，其实无非就是染色。\n\n\n![photo](src/photo/27.png) \n \n[BiparitionDecetion](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/BipartitionDecetion.java)\n\n同构图\n\nNP 难 不能再多项式的问题是解决不了，但是无法证明是指数复杂度解决。\n\n平面图\n\n\n# 广度优先遍历\n\n回顾树的优先遍历，其实就是一个队列，实现每次将这个节点的孩子节点放入队列中，最终当队列空了，就说明\n树已经全部遍历过。对于一个节点，将所有的节点都遍历一边。\n\n\n[BFS](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/GraphBFS.java)\n\n\n复杂度 O(V+E)\n\n和深度优先遍历是一样的，如果是联通图的情况就是 O(E)\n\n无非就是顺序不一样。\n\n\n\n# 广度优先遍历应用\n\n## 路径问题\n\n![photo](src/photo/28.png) \n\n\nDFS : 0-\u003e6:[0, 1, 3, 2, 6]\n\nBFS : 0-\u003e6:[0, 2, 6]\n\n[SingleSourcePathBFS](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/SingleSourcePathBFS.java)\n\n\n## 使用 BFS 解决联通分量问题\n\n如果大家实际尝试一下，就会发现，这其实是非常简单的，我们要做的事情，近乎就是讲 dfs 函数替换成 bfs 函数而已。\n\n\n注意，以下代码沿用我们在上一章第三小节的代码风格，visited数组是一个整型数组，-1 代表没有遍历，非负整数代表对应的连通分量的id。\n\n    // 使用 BFS 解决无向图的联通分量问题\n    public class CC {\n\n    private Graph G;\n    private int[] visited;\n    private int cccount = 0;\n\n    public CC(Graph G){\n\n        this.G = G;\n        visited = new int[G.V()];\n        for(int i = 0; i \u003c visited.length; i ++)\n            visited[i] = -1;\n\n        for(int v = 0; v \u003c G.V(); v ++)\n            if(visited[v] == -1){\n                // 只是这里调用 bfs 而已\n                bfs(v, cccount);\n                cccount ++;\n            }\n    }\n\n代码如下：\n\n[CCBfs](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/CCBfs.java)\n\n\n## 使用 BFS 求解环检测问题\n\n可以回忆一下，在上一章，我们使用 DFS 解决了环检测问题。同理的，BFS 也可以解决环检测问题：）\n\n和 DFS 的思路一样，大家可以回忆一下。使用 DFS 做环检测，只需要看到某一个顶点之前曾经遍历过，同时不是当前顶点的前一个顶点，就说明我们找到了一个环。\n\n[CycleDecetionBFS](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/CycleDecetionBFS.java)\n\n\n## 使用 BFS 解决二分图检测问题 \n\n可以回忆一下，在上一章，我们使用 DFS 解决了二分图检测问题。同理的，BFS 也可以解决环检测问题：）\n\n和 DFS 的思路一样，大家可以回忆一下。使用 DFS 做二分图检测，需要不断对没有遍历过的顶点进行染色，对遍历过的顶点，查看是否矛盾。如果产生矛盾，即某条边的两个端点颜色一样，则说明整张图不可能是二分图，否则，整张图就是二分图。\n\n在这里，我首先强烈建议大家自己尝试基于 BFS，设计一个算法类，解决二分图检测问题。整个类的接口，应该和我们在学习 DFS 时设计的 BipartitionDetection 类是一样的，只不过，内部实现是使用 BFS 而不是 DFS：）\n\n[BipartitionDecetionBFS](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/BipartitionDecetionBFS.java)\n\n\n#BFS 性质\n\n无权图最短路径 \n\n其实就是 BFS 求出路径就是 最短路径\n\n不可能后遍历的节点 一定是基于后遍历的节点\n\n![photo](src/photo/29.png) \n\n无权图的最短路径\n\n[USSSPath](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/USSSPath.java)\n\n\n## 比较BFS 和 DFS \n\n图的广度优先遍历BFS \n\n无权图的最短路径\n\n\n![photo](src/photo/30.png) \n\n其实很相似，无非就是修改stack 和 queue\n\n其实也可以用随机使用其他模型，比如随机队列。\n\n\n## 图论建模\n\n算法笔试中图论问题的书写\n\n###  leetcode 785\n\n[785](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/leetcode785.java)\n\n\n### leetcode 695\n\n![photo](src/photo/31.png) \n\n四联通 ： 四个方向[[-1,0],[0,1],[1,0],[0,-1]]\n\n    x,y\n    for(d = 0;d \u003c4;d++){\n        nextx = x + dist[d][0]\n        nexty = y + dist[d][1];\n    }\n\n\nFloodfill 算法\n\n![photo](src/photo/32.png) \n\n\n其实就是从一个点就是遍历，到所有的匹配算法。\n\n\n更多的应用：填色问题\n\n魔棒其实就是：floodfill 算法\n\n\nleetcode 200 岛屿的数量\n\nleetcode 1020 飞地的数量\n\nleetcode 130 \n\nleetcode 733 图像处理\n\nleetcode 1034 边框着色\n\nleetcode 529 扫雷\n\nleetcode 827 最大人工岛\n\n\n关于leetcode 659 号问题的研究。 \n\n\n我们可以更加优化，我们不需要visited 数组。\n    \n# 人工智能和图论搜素\n\nleetcode 1091\n\n\nBFS , 八联通\n[1091](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/leetcode1091.java)\n\n\nleetcode 752 Open the Lock\n\n一道智力题\n\n有两个水桶，一个装5升，一个装3升。 怎么利用这两个水桶，得到4升水？\n\n\n![photo](src/photo/33.png) \n\n\n状态压缩 10 *x + y\n\n\n\n[WaterPuzzle](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/WaterPuzzle.java)\n\n\n![photo](src/photo/34.png) \n\n\n\n\n# 桥\n\n\n![photo](src/photo/35.png) \n\n\n让我们一定能保证的话，可以能够保证两个联通分量，相互链接。\n\n\n![photo](src/photo/36.png) \n\n\n![photo](src/photo/37.png) \n\n![photo](src/photo/38.png) \n\n![photo](src/photo/39.png) \n\n\nBFS 遍历树和DFS 遍历树\n\n能不能使用BFS遍历？\n不能\n\n### 遍历树\n\nDFS 遍历树\n![photo](src/photo/40.png)\n \n### 前向边：在遍历树上的边\n### 后向边 ： 图中的非遍历树边可以指向自己的祖先结点\n\n\n![photo](src/photo/41.png)\n### 横叉边\n\n所以必须通过DFS去寻找桥\n\n![photo](src/photo/42.png)\n\n## 割点\n\n![photo](src/photo/43.png)\n\n![photo](src/photo/45.png)\n \n![photo](src/photo/44.png) \n\n##哈密尔顿回路和路径\n\n![photo](src/photo/46.png) \n\n![photo](src/photo/47.png) \n\n\n![photo](src/photo/48.png) \n\n![photo](src/photo/49.png) \n\n\nNP难，我们还没有多项式的算法无法解出。    \n\n暴力求解\n\n\n![photo](src/photo/50.png) \n\n回溯解法\n\nO(n!)\n[HamiltonLoop](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/HamiltionLoop.java)\n\n##状态压缩\n\n二维坐标用一个数字表示 \n两个桶的水量用一个两位数表示\n\n### 看是否为1\n![photo](src/photo/51.png) \n\n因为是有符号的就是31位，一般不会超过31位，还不行就用63位，long类型              \n\n![photo](src/photo/52.png) \n### 修改数值\n\n![photo](src/photo/54.png) \n反之做减法\n\n![photo](src/photo/55.png)\n\n![photo](src/photo/56.png) \n\n位运算\n\n####基于状态压缩的哈密尔顿路径\n[HamiltonLoop](https://github.com/HuichuanLI/play-with-graph-algorithme/blob/master/src/HamiltionLoopOptimsation.java)\n\n\n###记忆化搜说\n\n\n![photo](src/photo/57.png)\n  \n![photo](src/photo/59.png) \n\n####O(n!) vs O(n*2^n)\n\n是把所有的排列组合，其实可能记忆化算搜说可能其实比较大。\n\n\n## 欧拉回路和欧拉路径\n哈密尔顿回路 从一个点出发，沿着边行走，经过每个顶点恰好一次，之后再回到出发点\n\n\n一个点出发，沿着边行走，经过每个边恰好一次，之后再回到出发点\n\n\n![photo](src/photo/60.png)\n  \n![photo](src/photo/61.png) \n\n![photo](src/photo/62.png) \n\n### 寻找欧拉回路三种算法\n\n#### 回溯法  指数级 O(n!)\n#### Fleury算法 选择走不走桥的边 贪心算法比较好\n##### O((v+E)^2)\n##### O(E^2)\n\n#### Hierholzer算法详解\n\n![photo](src/photo/63.png)\n\n![photo](src/photo/64.png)\n\n![photo](src/photo/65.png) \n \n \n # 带权图\n \n \n![photo](src/photo/66.png) \n \n \n![photo](src/photo/67.png) \n \n \n \n## 最小生成树\n尽量使用最小的边，最终选择v-1条边\n布线设计\n\n切分定理\n\n![photo](src/photo/68.png) \n\n横切边中的最短边，属于最小生成树\n\n### kruskal 算法 \n- 贪心算法\n\nO(ElogE)最大的时间其实就是排序边\n\n### Prim 算法\n\n![photo](src/photo/69.png) \n\nO(ElogE) 最大的时间其实就是排序边\n\n\n## 最短路径\n\n- 只有正权边\n### Dijkstra算法\n\n![photo](src/photo/70.png) \n\n![photo](src/photo/71.png) \nO(V^2)\n\n### Dijkstra算法优化\n\n![photo](src/photo/72.png) \nO(ElogE)\n\n### Bellman-Ford算法\n- 松弛操作\n\n![photo](src/photo/74.png)\n \n![photo](src/photo/73.png) \n\n- 负权环\n\n![photo](src/photo/75.png) \n\n![photo](src/photo/76.png) \n\n\n### Floyd算法\n\n所有点对的最短路径\n\n![photo](src/photo/77.png) \n\n![photo](src/photo/78.png)\n\n![photo](src/photo/79.png)\n\n\n![photo](src/photo/81.png)\n\n![photo](src/photo/82.png)\n\n\n## 有向图\n- 任务调度\n- 学习计划\n- 互联网链接\n\n### 有向图算法\n#### 我们不考虑算法\n- floodfill\n- 最小生成树\n- 桥和割点\n- 二分图检测\n#### 不需要改变算法\n- DFS\n- BFS\n- Dijsktra/Floyd/Bellman-Ford\n\n### 有向图环检测 \u0026\u0026 DAG\n\n![photo](src/photo/83.png)\n\n判断是否在路径上\n\n[CycleDirection](./src/Chapter12DirectedGraph/python/DirectedCycleDetection.py)\n\n![photo](src/photo/84.png)\n\n### Euler回路 出度和入度\n![photo](src/photo/85.png)\n\n### 拓扑排序(*****)\n\n![photo](src/photo/86.png)\n\n使用队列\n\n![photo](src/photo/87.png)\n\n![photo](src/photo/88.png)\n\n拓扑排序另一种算法：DFS的后序遍历\n\n![photo](src/photo/89.png)\n\n![photo](src/photo/90.png)\n\n不能进行环检测\n\n### 有向图的联通分量\n\n强连通分量，在一个强连通分量中， 任何两点都可达\n\n![photo](src/photo/91.png)\n\n\n将所有强连通分量看做一个点 得到的有向图一定是DAG \n\n### Kosaraju 算法 --求强联通分量\n\n![photo](src/photo/92.png)\n\n![photo](src/photo/93.png)\n\n![photo](src/photo/94.png)\n\n![photo](src/photo/95.png)\n\n## 网络流\n\n![photo](src/photo/96.png)\n\n![photo](src/photo/97.png)\n\n### Ford-Fulkerson思想\n\n![photo](src/photo/98.png)\n\n增广路径：就是所有的残量大于0，到终点\n\n\n![photo](src/photo/99.png)\n\n### Edmonds-Karp算法\n\n\n![photo](src/photo/100.png)\n\n![photo](src/photo/101.png)\n\n## 最大流算法建模\n\n![photo](src/photo/102.png)\n\n\n![photo](src/photo/103.png)\n\n\n## 匹配问题\n\n![photo](src/photo/104.png)\n\n    最大匹配：就是找大最多的边\n    完全匹配：所有的点都在匹配中\n    完全匹配一定是最大匹配， 最大匹配不一定是完全匹配\n\n### 使用最大流解决匹配问题\n\n![photo](src/photo/105.png)\n\n### 匈牙利算法 **\n\n![photo](src/photo/107.png)\n\n有增广路径，意味这匹配数可以增加1\n\nBFS 需要改进：来到右边的点，不需要寻路\n\nDFS实现\n\nO(V*E)\n\n## 总结\n![photo](src/photo/108.png)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhuichuanli%2Fplay-with-graph-algorithme","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhuichuanli%2Fplay-with-graph-algorithme","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhuichuanli%2Fplay-with-graph-algorithme/lists"}