Code Practice Journal | Day56_Graph06 Minimum Spanning Tree

2024-08-30 00:20

本文主要是介绍Code Practice Journal | Day56_Graph06 Minimum Spanning Tree,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 概念

生成树(Spanning Tree)

给定的图中选择一些边,使边连接图中所有节点但不成环,形成的子图即为生成树。

最小生成树(MST)

所有可能的生成树中,权重和最小的生成树即为最小生成树。

2. 算法

2.1 Kruskal

1、基本思想

对边按权重排序,注意加入边并保证不成环:
使用并查集来管理连接节点并检查是否成环

2、步骤:

对所有边按权重升序排列

初始化并查集

依次选择边,检查边的两个节点是否在统一连通分量中
        在:跳过此边
        不在:此边加入生成树,并合并两个节点所在连通分量

重复步骤

3、代码实现

class Program
{public class Edge : IComparable<Edge>{public int U, V, Weight;public Edge(int u, int v, int weight){U = u;V = v;Weight = weight;}public int CompareTo(Edge other){return Weight.CompareTo(other.Weight);}}public static int Find(int[] parent, int i){if (parent[i] == i)return i;return parent[i] = Find(parent, parent[i]);}public static void Union(int[] parent, int[] rank, int x, int y){int rootX = Find(parent, x);int rootY = Find(parent, y);if (rootX != rootY){if (rank[rootX] > rank[rootY]){parent[rootY] = rootX;}else if (rank[rootX] < rank[rootY]){parent[rootX] = rootY;}else{parent[rootY] = rootX;rank[rootX]++;}}}public static int KruskalMST(int V, List<Edge> edges){edges.Sort();int[] parent = new int[V + 1];int[] rank = new int[V + 1];for (int i = 1; i <= V; i++){parent[i] = i;rank[i] = 0;}int mstWeight = 0;foreach (var edge in edges){int u = edge.U;int v = edge.V;int w = edge.Weight;int rootU = Find(parent, u);int rootV = Find(parent, v);if (rootU != rootV){mstWeight += w;Union(parent, rank, rootU, rootV);}}return mstWeight;}public static void Main(string[] args){string[] firstLine = Console.ReadLine().Split();int V = int.Parse(firstLine[0]);int E = int.Parse(firstLine[1]);List<Edge> edges = new List<Edge>();for (int i = 0; i < E; i++){string[] edgeInput = Console.ReadLine().Split();int u = int.Parse(edgeInput[0]);int v = int.Parse(edgeInput[1]);int weight = int.Parse(edgeInput[2]);edges.Add(new Edge(u, v, weight));}Console.WriteLine(KruskalMST(V, edges));}
}

2.2 Prime

1、基本思想

从一个节点开始,逐步选择连接权重最小的边来扩展树:
已访问节点集合到未访问节点集合的最短距离

2、步骤:

选择一个起始节点,标记为已访问

将所有连接到已访问节点集合的边加入队列

从队列中选择权重最小的边,并检查这条边是否连接了一个未访问的节点
        是:将该节点标记为已访问,加入已访问节点集合

重复步骤

3、代码实现

class Program
{public class Edge{public int V, Weight;public Edge(int v, int weight){V = v;Weight = weight;}}public static int PrimMST(int V, List<Edge>[] graph){bool[] visited = new bool[V + 1];int[] minEdge = new int[V + 1];for (int i = 1; i <= V; i++)minEdge[i] = int.MaxValue;int mstWeight = 0;minEdge[1] = 0;for (int i = 0; i < V; i++){int v = -1;for (int j = 1; j <= V; j++){if (!visited[j] && (v == -1 || minEdge[j] < minEdge[v]))v = j;}if (minEdge[v] == int.MaxValue)return -1;mstWeight += minEdge[v];visited[v] = true;foreach (var edge in graph[v]){if (!visited[edge.V] && edge.Weight < minEdge[edge.V]){minEdge[edge.V] = edge.Weight;}}}return mstWeight;}public static void Main(string[] args){string[] firstLine = Console.ReadLine().Split();int V = int.Parse(firstLine[0]);int E = int.Parse(firstLine[1]);List<Edge>[] graph = new List<Edge>[V + 1];for (int i = 1; i <= V; i++)graph[i] = new List<Edge>();for (int i = 0; i < E; i++){string[] edgeInput = Console.ReadLine().Split();int u = int.Parse(edgeInput[0]);int v = int.Parse(edgeInput[1]);int weight = int.Parse(edgeInput[2]);graph[u].Add(new Edge(v, weight));graph[v].Add(new Edge(u, weight));}Console.WriteLine(PrimMST(V, graph));}
}

这篇关于Code Practice Journal | Day56_Graph06 Minimum Spanning Tree的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1119264

相关文章

树(Tree)——《啊哈!算法》

树 什么是树?树是一种特殊的图,不包含回路的连通无向树。 正因为树有着“不包含回路”这个特点,所以树就被赋予了很多特性。 一棵树中的任意两个结点有且仅有唯一的一条路径连通。一棵树如果有n个结点,那么它一定恰好有n-1条边。在一棵树中加一条边将会构成一个回路。 一棵树有且只有一个根结点。 没有父结点的结点称为根结点(祖先)。没有子结点的结点称为叶结点。如果一个结点既不是根结点也不是叶

Debugging Lua Project created in Cocos Code IDE creates “Waiting for debugger to connect” in Win-7

转自 I Installed Cocos Code IDE and created a new Lua Project. When Debugging the Project(F11) the game window pops up and gives me the message waiting for debugger to connect and then freezes. Also a

LLVM入门2:如何基于自己的代码生成IR-LLVM IR code generation实例介绍

概述 本节将通过一个简单的例子来介绍如何生成llvm IR,以Kaleidoscope IR中的例子为例,我们基于LLVM接口构建一个简单的编译器,实现简单的语句解析并转化为LLVM IR,生成对应的LLVM IR部分,代码如下,文件名为toy.cpp,先给出代码,后面会详细介绍每一步分代码: #include "llvm/ADT/APFloat.h"#include "llvm/ADT/S

VS Code 调试go程序的相关配置说明

用 VS code 调试Go程序需要在.vscode/launch.json文件中增加如下配置:  // launch.json{// Use IntelliSense to learn about possible attributes.// Hover to view descriptions of existing attributes.// For more information,

226 Invert Binary Tree

//226 Invert Binary Tree//算法思路:主要使用递归算法public class Solution {public TreeNode invertTree(TreeNode root) {//1 出口 空节点if (root==null)return null;//2 递归 调用自己TreeNode left = root.left;TreeNode right = ro

Linux日志-journal日志

作者介绍:简历上没有一个精通的运维工程师。希望大家多多关注作者,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux 系统中的日志是记录系统活动和事件的重要工具,它们可以帮助管理员监视系统状态、调查问题以及了解系统运行状况。主要涉及到系统日志,登录日志,定时任务日志,监控日志,崩溃日志,二进制日志等内容,这些日志都存储在/var/log目录下,有的日志文本格式,可以直接使用

code: 400, msg: Required request body is missing 错误解决

引起这个错误的原因是,请求参数按照get方式给。 应该给json字符串才对 补充: 1. @RequestBody String resource 加@RequestBody必须给json字符串,否则会报错400,记如标题错误。 不加这个的进行请求的话,其实post和get就没有什么区别了。 2. List<String> indexCodes=(List<String>)json.

【Hdu】Minimum Inversion Number(逆序,线段树)

利用线段树在nlogn的时间复杂度内求一段数的逆序。 由于给的序列是由0 ~ n -1组成的,求出初始的逆序之后可以递推出移动之后的逆序数。 #include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const in

iOS项目发布提交出现invalid code signing entitlements错误。

1、进入开发者账号,选择App IDs,找到自己项目对应的AppId,点击进去编辑, 2、看下错误提示出现  --Specifically, value "CVYZ6723728.*" for key "com.apple.developer.ubiquity-container-identifiers" in XX is not supported.-- 这样的错误提示 将ubiquity

解决服务器VS Code中Jupyter突然崩溃的问题

问题 本来在服务器Anaconda的Python环境里装其他的包,装完了想在Jupyter里写代码验证一下有没有装好,一运行发现Jupyter崩溃了!?报错如下所示 Failed to start the Kernel. ImportError: /home/hujh/anaconda3/envs/mia/lib/python3.12/lib-dynload/_sqlite3.cpython-