08-图7 公路村村通(C)
很明显聪明的同学已经发现,这是一个稠密图,所以用邻接矩阵。可以很好的表达,比邻接表有优势,所以,采用邻接矩阵破题,
当然也可以用邻接表,仔细观察我的AC,会发现其实都一样,只是存储形式不一样罢了。
很明显,这是一个最小生成树问题,也可以认为贪心算法,接下来我将分别展示两个实现路径,第一个 prim 算法, 第二个kruskal算法。
第一个 prim 算法,哈哈,原来是我最开始搞错方向了,并未理解prim算法,这下也是让我印象深刻了。
测试点 提示 内存(KB) 用时(ms) 结果 得分 0 sample换数字,各种回路判断 192 4 答案正确
15 / 15 1 M<N-1,不可能有生成树 192 4 答案正确
2 / 2 2 M达到N-1,但是图不连通 192 4 答案正确
2 / 2 3 最大N和M,连通 4284 8 答案正确
5 / 5 4 最大N和M,不连通 4160 7 答案正确
6 / 6
第二个kruskal算法,实际应用很简单,果然馒头嚼碎也不见得好吸收,一点点啃食的过程,也是非常锻炼计算思维。
按道理来说,应该是kruskal算法快,但是也就一个O(N^2) 与O(NlogN),可以看出来在1000个数据点(最大N(1000),M(3000))下,区别还是有的。
测试点 提示 内存(KB) 用时(ms) 结果 得分 0 sample换数字,各种回路判断 188 4 答案正确
15 / 15 1 M<N-1,不可能有生成树 188 4 答案正确
2 / 2 2 M达到N-1,但是图不连通 188 4 答案正确
2 / 2 3 最大N和M,连通 4156 7 答案正确
5 / 5 4 最大N和M,不连通 4160 6 答案正确
6 / 6
现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。
输入格式:
输入数据包括城镇数目正整数 n(≤1000)和候选道路数目 m(≤3n);随后的 m 行对应 m 条道路,每行给出 3 个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从 1 到 n 编号。
输出格式:
输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出 −1,表示需要建设更多公路。
输入样例:
6 15 1 2 5 1 3 3 1 4 7 1 5 4 1 6 2 2 3 4 2 4 6 2 5 2 2 6 6 3 4 6 3 5 1 3 6 1 4 5 10 4 6 8 5 6 3输出样例:
12
第一个 prim 算法,我的AC:
采用了,最小堆 + prim,.
#include<stdio.h> #include<stdlib.h> #include<stdbool.h>#define MaxVertex 1001 #define INFITY 100001 #define MinValue -1typedef struct ENode *Edge; struct ENode{int V1, V2;int Weight; };typedef struct GNode *MGraph; struct GNode{int Nv;int Ne;int G[MaxVertex][MaxVertex]; };typedef struct Sign_Dist_VNode DistNode; struct Sign_Dist_VNode{int V;int Weight; };typedef struct Heap *MinHeap; struct Heap{DistNode *Data;int Size; };MGraph Build_Graph(); MGraph Init_Graph(); void Insert_Graph(MGraph M, Edge E); MinHeap Init_Heap(int N); void Creat_Heap(MGraph M, MinHeap H, int Vertex, bool* Visited, bool *collected); void Push_Heap(MinHeap H, int index, int Weight, bool *collected); void Counterpoise_Heap(MinHeap H, int index, int V, int Weight); bool IsEmpty_Heap(MinHeap H); DistNode Pop_Heap(MinHeap H, bool *collected); void Prim(MGraph M, MinHeap H, bool* Visited, int *dist); void Print_Result(int N, int *dist, bool* Visited);int main() {MGraph M;MinHeap H;int *dist;bool *Visited;M = Build_Graph();H = Init_Heap(M ->Nv);dist = (int*)malloc(sizeof(int) * M ->Nv);Visited = (bool*)calloc(M ->Nv, sizeof(bool));Prim(M, H, Visited, dist);Print_Result(M ->Nv, dist, Visited);return 0; }void Prim(MGraph M, MinHeap H, bool* Visited, int *dist) {int j;bool *collected;collected = (bool*)calloc(M ->Nv, sizeof(bool));for(j = 1; j < M ->Nv; j++){dist[j] = M ->G[0][j];}DistNode Data;Creat_Heap(M, H, 0, Visited, collected);Visited[0] = true;dist[0] = 0;while(Data = Pop_Heap(H, collected), Data.Weight > 0){Visited[Data.V] = true;for(j = 0; j < M ->Nv; j++){if(!Visited[j] && M ->G[Data.V][j] < INFITY && (dist[j] > M ->G[Data.V][j])){dist[j] = M ->G[Data.V][j];Push_Heap(H, j, dist[j], collected);//有人会问,这样不会产生数据重复吗,注意Visited,遵循一次访问原则。}}} } void Print_Result(int N, int *dist, bool* Visited) {int i, cost = 0;for(i = 0; i < N; i++){if(!Visited[i]){printf("-1\n");return ;}cost += dist[i];}printf("%d\n", cost);return ; } MGraph Build_Graph() {MGraph M;Edge E;M = Init_Graph();E = (Edge)malloc(sizeof(struct ENode));for(int i = 0; i < M ->Ne; i++){scanf("%d %d %d", &E ->V1, &E ->V2, &E ->Weight);E ->V1 --; E ->V2 --;Insert_Graph(M, E);}return M; } MGraph Init_Graph() {MGraph M;M = (MGraph)malloc(sizeof(struct GNode));scanf("%d %d", &M ->Nv, &M ->Ne);for(int i = 0; i < (M ->Nv); i++){for(int j = 0; j < (M ->Nv); j++){M ->G[i][j] = INFITY;}}return M; } void Insert_Graph(MGraph M, Edge E) {M ->G[E ->V1][E ->V2] = E ->Weight;M ->G[E ->V2][E ->V1] = E ->Weight; }void Creat_Heap(MGraph M, MinHeap H, int Vertex, bool* Visited, bool *collected) {for(int j = 0; j < M ->Nv; j++){if(M ->G[Vertex][j] < INFITY && !Visited[j]){Push_Heap(H, j, M ->G[Vertex][j], collected);}} } MinHeap Init_Heap(int N) {MinHeap H;H = (MinHeap)malloc(sizeof(struct Heap));H ->Data = (DistNode*)malloc(sizeof(DistNode) * (N + 1));H ->Data[0].Weight = MinValue;H ->Size = 0;return H; } void Push_Heap(MinHeap H, int index, int Weight, bool *collected) {int i;if(collected[index]){for(i = 1; i <= H ->Size; i++){if(index == H ->Data[i].V){H ->Data[i].Weight = Weight;Counterpoise_Heap(H, index, i, Weight);return ;}}}else{i = ++(H ->Size);Counterpoise_Heap(H, index, i, Weight);collected[index] = true;return ;} } void Counterpoise_Heap(MinHeap H, int index, int i, int Weight) {for(; Weight < H ->Data[i/2].Weight; i /= 2){H ->Data[i].Weight = H ->Data[i/2].Weight;H ->Data[i].V = H ->Data[i/2].V;}H ->Data[i].Weight = Weight;H ->Data[i].V = index;return ; } bool IsEmpty_Heap(MinHeap H) {return (H ->Size == 0); } DistNode Pop_Heap(MinHeap H, bool *collected) {DistNode Min, Temp;int Parent, Child;if(IsEmpty_Heap(H)){return H ->Data[0];}Min = H ->Data[1];Temp = H ->Data[H ->Size --];collected[Min.V] = false;for(Parent = 1; Parent *2 < H ->Size; Parent = Child){Child = Parent * 2;if(H ->Data[Child].Weight > H ->Data[Child + 1].Weight){Child++;}if(Temp.Weight <= H ->Data[Child].Weight){break;}else{H ->Data[Parent].Weight = H ->Data[Child].Weight;H ->Data[Parent].V = H ->Data[Child].V;}}H ->Data[Parent].Weight = Temp.Weight;H ->Data[Parent].V = Temp.V;return Min; }
第二个kruskal算法, 最小堆+并查树+Kruskal。
#include<stdio.h> #include<stdlib.h> #include<stdbool.h>#define MaxVertex 1001 #define INFITY 100001 #define MinValue -1typedef struct ENode Edge; struct ENode{int V1, V2;int Weight; };typedef struct GNode *MGraph; struct GNode{int Nv;int Ne;int G[MaxVertex][MaxVertex]; };typedef struct Heap *MinHeap; struct Heap{Edge *Data;int Size; };//便于并查树算法理解,有心吧。 typedef struct UnionFind *UF; struct UnionFind{int Parent; };MGraph Build_Graph(); MGraph Init_Graph(); void Insert_Graph(MGraph M, Edge E); MinHeap Init_Heap(int N); MinHeap Creat_Heap(MGraph M); void Push_Heap(MinHeap H, int V1, int V2, int Weight); bool IsEmpty_Heap(MinHeap H); Edge Pop_Heap(MinHeap H); UF Init_UnionFind(int VertexNum); void Union_Value(UF T, int V1, int V2); int Find_Root(UF T, int V); bool Check_Loop(UF T, int V1, int V2); void Kruskal(MGraph M, MinHeap H, UF T, bool *Visited, int *dist);int main() {MGraph M;MinHeap H;UF T;int *dist;bool *Visited;M = Build_Graph();H = Creat_Heap(M); T = Init_UnionFind(M ->Nv);dist = (int*)malloc(sizeof(int) * M ->Nv);Visited = (bool*)calloc(M ->Nv, sizeof(bool));Kruskal(M, H, T, Visited, dist);return 0; } void Kruskal(MGraph M, MinHeap H, UF T, bool *Visited, int *dist) {Edge Data;int i = 1;int cost = 0;while(Data = Pop_Heap(H), (Data.Weight > 0 && i < M ->Nv)){if(!Check_Loop(T, Data.V1, Data.V2)){Union_Value(T, Data.V1, Data.V2);cost += Data.Weight;i++;}}if(i != M ->Nv){printf("-1\n");}else{printf("%d\n", cost);} }MGraph Build_Graph() {MGraph M;Edge E;M = Init_Graph();for(int i = 0; i < M ->Ne; i++){scanf("%d %d %d", &E.V1, &E.V2, &E.Weight);E.V1 --; E.V2 --;Insert_Graph(M, E);}return M; } MGraph Init_Graph() {MGraph M;M = (MGraph)malloc(sizeof(struct GNode));scanf("%d %d", &M ->Nv, &M ->Ne);for(int i = 0; i < (M ->Nv); i++){for(int j = 0; j < (M ->Nv); j++){M ->G[i][j] = INFITY;}}return M; } void Insert_Graph(MGraph M, Edge E) {M ->G[E.V1][E.V2] = E.Weight;M ->G[E.V2][E.V1] = E.Weight; }MinHeap Creat_Heap(MGraph M) {MinHeap H;H = Init_Heap(M ->Ne);for(int i = 0; i < M ->Nv; i++)for(int j = i + 1; j < M ->Nv; j++){if(M ->G[i][j] < INFITY){Push_Heap(H, i, j, M ->G[i][j]);}}return H; } MinHeap Init_Heap(int N) {MinHeap H;H = (MinHeap)malloc(sizeof(struct Heap));H ->Data = (Edge*)malloc(sizeof(Edge) * (N + 1));H ->Data[0].Weight = MinValue;H ->Size = 0;return H; } void Push_Heap(MinHeap H, int V1, int V2, int Weight) {int i;i = ++(H ->Size);for(; Weight < H ->Data[i/2].Weight; i /= 2){H ->Data[i].Weight = H ->Data[i/2].Weight;H ->Data[i].V1 = H ->Data[i/2].V1;H ->Data[i].V2 = H ->Data[i/2].V2;}H ->Data[i].Weight = Weight;H ->Data[i].V1 = V1;H ->Data[i].V2 = V2;return ; }bool IsEmpty_Heap(MinHeap H) {return (H ->Size == 0); } Edge Pop_Heap(MinHeap H) {Edge Min, Temp;int Parent, Child;if(IsEmpty_Heap(H)){return H ->Data[0];}Min = H ->Data[1];Temp = H ->Data[H ->Size --];for(Parent = 1; Parent *2 < H ->Size; Parent = Child){Child = Parent * 2;if(H ->Data[Child].Weight > H ->Data[Child + 1].Weight){Child++;}if(Temp.Weight <= H ->Data[Child].Weight){break;}else{H ->Data[Parent].Weight = H ->Data[Child].Weight;H ->Data[Parent].V1 = H ->Data[Child].V1;H ->Data[Parent].V2 = H ->Data[Child].V2;}}H ->Data[Parent].Weight = Temp.Weight;H ->Data[Parent].V1 = Temp.V1;H ->Data[Parent].V2 = Temp.V2;return Min; } UF Init_UnionFind(int VertexNum) {UF T;T = (UF)malloc(sizeof(struct UnionFind) * (VertexNum + 1));for(int i = 0; i < VertexNum; i++){T[i].Parent = -1;}return T; } void Union_Value(UF T, int V1, int V2) {int Root1, Root2;Root1 = Find_Root(T, V1);Root2 = Find_Root(T, V2);if(T[Root1].Parent < T[Root2].Parent){T[Root1].Parent += T[Root2].Parent;T[Root2].Parent = Root1;}else{T[Root2].Parent += T[Root1].Parent;T[Root1].Parent = Root2;} } int Find_Root(UF T, int V) {if(T[V].Parent < 0){return V;}return Find_Root(T, T[V].Parent); } bool Check_Loop(UF T, int V1, int V2) {if(Find_Root(T, V1) == Find_Root(T, V2)){return true;}else{return false;} }
2024.9.6-错误借鉴,哈哈,我竟然,好吧,就是没有好好听课,不是最短路,而是最小边,之前的样例我感觉只是运气吧。
测试点 提示 内存(KB) 用时(ms) 结果 得分 0 sample换数字,各种回路判断 184 4 答案正确
15 / 15 1 M<N-1,不可能有生成树 188 4 答案正确
2 / 2 2 M达到N-1,但是图不连通 316 4 答案正确
2 / 2 3 最大N和M,连通 4156 8 答案错误
0 / 5 4 最大N和M,不连通 4156 7 答案正确
6 / 6 void Prim(MGraph M, MinHeap H, bool* Visited, int *dist) {int j;bool *collected;collected = (bool*)calloc(M ->Nv, sizeof(bool));for(j = 0; j < M ->Nv; j++){dist[j] = INFITY;}DistNode Data;Creat_Heap(M, H, 0, Visited, collected);Visited[0] = true;dist[0] = 0;while(Data = Pop_Heap(H, collected), Data.Weight > 0){if(!Visited[Data.V] && dist[Data.V] > Data.Weight){dist[Data.V] = Data.Weight;}Visited[Data.V] = true;for(j = 0; j < M ->Nv; j++){if(!Visited[j] && M ->G[Data.V][j] < INFITY && (dist[j] > dist[Data.V] + M ->G[Data.V][j])){dist[j] = M ->G[Data.V][j];Push_Heap(H, j, dist[j], collected);//有人会问,这样不会产生数据重复吗,注意Visited,遵循一次访问原则。}}} }
相关文章:
08-图7 公路村村通(C)
很明显聪明的同学已经发现,这是一个稠密图,所以用邻接矩阵。可以很好的表达,比邻接表有优势,所以,采用邻接矩阵破题, 当然也可以用邻接表,仔细观察我的AC,会发现其实都一样,只是存储…...
Java-sleep()、wait()、join()、yield()的区别
关于线程,作为八股文面试中必问点,我们需要充分了解sleep()、wait()、join()以及yield()的区别。在正式开始之前先让我们了解两个概念:锁池和等待池 1.锁池 所有需要竞争同步锁的线程都会放在锁池当中,比如当前对象的锁已经被其中…...
Linux命令的补全和自动完成完全开启
前言 在安装好RockyLinux8.8后,输入dn后,按下“TAB”能自动提示,但在输入dnf make后,按下“TAB”不能实现自动补全,如果要使Linux的Bash支持完整的自动提示和补全功能,还需要执行一些其它操作。 内容 1、…...
Deep Active Contours for Real-time 6-DoF Object Tracking
这篇论文解决了从RGB视频进行实时6自由度(6-DoF)物体跟踪的问题。此前的基于优化的方法通过对齐投影模型与图像来优化物体姿态,这种方法依赖于手工设计的特征,因此容易陷入次优解。最近的基于学习的方法使用神经网络来预测姿态&am…...
IDEA安装教程配置java环境(超详细)
引言 IntelliJ IDEA 是一款功能强大的集成开发环境(IDE),广泛用于 Java 开发,但也支持多种编程语言,如 Kotlin、Groovy 和 Scala。本文将为你提供一步一步的指南,帮助你在 Windows 系统上顺利安装 Intelli…...
Excel文档的读取(1)
熟悉使用Excel的同学应该都知道,在单个Excel表格里想要分商品计算总销售额,使用数据透视表也可以非常快速方便的获得结果。但当有非常大量的Excel文件需要处理时,每一个Excel文件单独去做数据透视也会消耗大量的时间。就算使用Power Query这样…...
Linux:体系结构和操作系统管理
目录 一、冯诺依曼体系结构 1.问题1 2.问题2 二、操作系统管理 一、冯诺依曼体系结构 本章将会谈论一下对冯诺依曼计算机体系结构的理解。 在2024年,几乎所有的计算机,都遵守冯诺依曼体系结构。 冯诺依曼体系结构是应用在硬件层面的,而硬…...
c++ install boost lib
同步系统上的软件包列表 sudo apt-update 整个库安装: sudo apt-get install libboost-all-dev 安装部分库: sudo apt-get install libboost-thread-dev sudo apt-get install libboost-filesystem-dev 链接时加上: -lboost_filesystem -lboost_system 例如: g -Wall -o bo…...
文件加密最简单的方法有哪些?十个电脑文件加密方法【超详细】
在当今数字化和信息化的时代,数据已成为企业最重要的资产之一。内部数据外泄不仅可能导致商业秘密的丧失,还可能对企业的声誉和财务健康造成严重影响。为了有效防止内部数据外泄,企业需要实施综合的防泄密解决方案。以下是十大最佳防泄密解决…...
IPv6地址的表示方法
IPv6地址总长度为128比特,通常分为8组,每组为4个十六进制数的形式,每组十六进制数间用冒号分隔。 例如:2409:8745:039a:c700:0000:0000:0162,这是IPv6地址的首选格式。 为了书写方便,IPv6还提供了压缩格式…...
Kubernetes 之 kubelet 与 CRI、CNI 的交互过程
序言 当一个新的 Pod 被提交创建之后,Kubelet、CRI、CNI 这三个组件之间进行了哪些交互? Kubelet -> CRI -> CNI 如上图所示: Kubelet 从 kube-api-server 处监听到有新的 pod 被调度到了自己的节点且需要创建。Kubelet 创建 sandbo…...
【python】OpenCV—Age and Gender Classification
文章目录 1、任务描述2、网络结构2.1 人脸检测2.2 性别分类2.3 年龄分类 3、代码实现4、结果展示5、参考 1、任务描述 性别分类和年龄分类预测 2、网络结构 2.1 人脸检测 输出最高的 200 个 RoI,每个 RoI 7 个值,(xx,xx&#x…...
python安装换源
安装 python 使用演示的是python 3.8.5 安装完成后,如下操作打开命令行:同时按 “WindowsR” > 输入 “cmd” -> 点击确定 python换源 临时换源: #清华源 pip install markdown -i https://pypi.tuna.tsinghua.edu.cn/simple # 阿里…...
JavaScript练手小技巧:利用鼠标滚轮控制图片轮播
近日,在浏览网站的时候,发现了一个有意思的效果:一个图片轮播,通过上下滚动鼠标滚轮控制图片的上下切换。 于是就有了自己做一个的想法,顺带复习下鼠标滚轮事件。 鼠标滚轮事件,参考这篇文章:…...
搭建Eureka高可用集群 - day03
全部代码发出来了 搭建服务提供者 步骤: 1.创建项目,引入依赖 2.添加Eureka相关配置 3.添加EnableEurekaClient注解 4.测试运行 步骤1:创建项目,引入依赖 使用Spring Initializr方式创建一个名称为eureka-provider的Sprin…...
并行程序设计基础——并行I/O(2)
目录 一、显式偏移的并行文件读写 1、阻塞方式 1.1 MPI_FILE_READ_AT 1.2 MPI_FILE_WRITE_AT 1.3 MPI_FILE_READ_AT_ALL 1.4 MPI_FILE_WRITE_AT_ALL 2、非阻塞方式 2.1 MPI_FILE_IREAD_AT 2.2 MPI_FILE_IWRITE_AT 3、两步非阻塞组调用 3.1 MPI_FILE_READ_AT_ALL_BEG…...
Java三种创建多线程的方法
线程是什么: 进程是程序的一次动态执行的过程,线程是进程中执行运算最小单位,一个进程在其执行过程中可以产生多个线程,而线程必须在某个进程内执行。 如果在一个进程中同时运行了多个线程(必须包含一个主线程&#…...
828华为云征文 | 云上私人数据管家,jMalCloud个人网盘在华为云Flexus的Docker化部署实践
华为云服务器Flexus X实例介绍 华为云Flexus云服务器X实例,是由国家科技进步奖获得者、华为公司Fellow、华为云首席架构师顾炯炯牵头研发。它基于擎天QingTian架构、瑶光云脑、盘古大模型等根技术创新,是业界首款应用驱动的柔性算力云服务器,…...
C# 开源教程带你轻松掌握数据结构与算法
目录 前言 项目介绍 项目特点 项目展示 1、内容导图 2、部分目录 3、源码示例 项目地址 最后 前言 在项目开发过程中,理解数据结构和算法如同掌握盖房子的秘诀。算法不仅能帮助我们编写高效、优质的代码,还能解决项目中遇到的各种难题。 给大家…...
由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(五)
概述 在 WWDC 24 中,苹果推出了数据库框架 SwiftData 2.0 版本。其新加入的历史记录追踪(History Trace)机制着实让秃头码农们“如痴如醉”了一番。 我们在之前的博文中已经介绍了 History Trace 是如何处理数据新增操作的。而在这里,我们将再接再厉来完成数据删除时的全盘…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
