图论(二)-图的建立

引言: 建图,将图放进内存的方法

            常用的建图方式:邻接矩阵,邻接链表,链式前向星    

一、邻接矩阵

                通过一个二维数组即可将图建立,邻接矩阵,考虑节点集合 V=\left \{ 1,2,3......n \right \} ,用一个二维数组定义邻接矩阵A\left [ 1.....n \right ]\left [ 1.....n \right ],满足以下

对于一个简单的有向图(或无向图),邻接矩阵如下:

    无向图:若 u 与 v 之间存在一条边,则 A[u][v]=A[v][u]=1 (两个方向)

    有向图:若有一条 u 指向 v 的边,则 A[u][v]=1;若有一条 v 指向 u 的边,则 A[v][u]=1(单向)

       邻接矩阵的空间消耗为O(V^{2}),无向图的邻接矩阵为对称矩阵。在某些情况下,只存储邻接矩阵的对角线及以上的部分,这样,图占用的存储空间可以减少一半。

二、邻接链表(vector建表)

       Adj为一个包含 V 条链表的数组,每个节点有一个链表,对于每个节点u∈V,邻接链表Adj[u]包含所有与节点u之间有边相连的节点v。

        如果G是一个有向图,则对于边(u,v)而言,节点 v 将出现在链表 Adj [ u ]里,所有邻接链表的长度之和等于 E;如果G是一个无向图,对于边(u,v),节点v将出现在链表 Adj [ u ] 里,节点 u 将出现在链表 Adj [ v ]里,所有邻接链表的长度之和为 2*E。

         对一个有向图通过vector建图:

        建图过程: 

            用结构体 node 存储两个数据(终点编号,边权值),建立 node 型的 vector 动态数组。建图也只需要将 结构体 直接插入 vector动态数组 末端即可。


typedef struct Node{int v;  //终点编号int w;  //起点到终点的边权
}Node;
vector<Node> map[201];    //用 vector 建立(不是严格意义上的链表)
void get_map(int m)
{for(int i=1;i<=m;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);Node tmp;tmp.v=v;tmp.w=w;map[u].push_back(tmp);    //将 终点节点v 和 边权w 加入 节点u 的链表末尾tmp.v=u;tmp.w=w;    //如果为无向图,反向边map[v].push_back(tmp);   // 将 将终点节点u 和边权w 加入 节点v 的链表末尾}
}

        邻接链表表示法的储存空间均为 O(V+E)

        vector 数组建图的应用(使用):

        最小生成树prim算法(完整代码):

#include<stdio.h>
#include<iostream>
#include<vector>
#include<queue>
#include<string.h>
#include<stdlib.h>
using namespace std;
struct node{int w;int v;friend bool operator<(node x,node y){ return x.w>y.w;} // 优先队列比较 按照w从小到大排?? 
};
priority_queue<node>q; // 建立数据类型为node结构体的优先队列 
int n,m,dis[1001],vis[1001];
vector<node>map[1001]; // 以node结构体的 vector数组 
int sum=0;
void prim(int s)
{memset(dis,0x3f,sizeof(dis)); // 初始化 memset(vis,0,sizeof(vis));dis[s]=0;q.push((node){0,s});while(!q.empty()){int u=q.top().v;q.pop();if(vis[u]) continue;vis[u]=1;sum+=dis[u];for(int i=0;i<map[u].size();i++) // vector建图的使用 {int v=map[u][i].v;int w=map[u][i].w;if(dis[v]>w){dis[v]=w;q.push((node){w,v});}}}
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);node tmp; // vector 建图 tmp.v=v;tmp.w=w;map[u].push_back(tmp);tmp.v=u; map[v].push_back(tmp); // 反向边 }prim(1);for(int i=1;i<=n;i++) {if(!vis[i]) {printf("orz");return 0;}}printf("%d",sum);return 0; }

三、链式前向星

             链式前向星所用结构体和相关变量,建图函数

struct node{int to,next,w;
}edge[2001];
int head[1001];
int cnt=0;
void addedge(int u,int v,int w)
{edge[++cnt].to=v;edge[cnt].next=head[u];edge[cnt].w=w;head[u]=cnt;
}

        初始化函数

//初始化函数
void init()
{memset(head,-1,sizeof(head));    //将head数组的值全置为-1.cnt=0;//初始化边的编号
}

对于一个有向图,用链式前向星建图: 

        关于结构体中 next 数组含义: 某一条边的起点连接的上一个编号比它小的边由于初始化,当某条边的next值为 -1 时,此条边为最后一条边。

 运用链式前向星遍历图的过程:

        首先根据节点 u 找到以 u 为起始点的边的编号,然后根据 next 找到下一条以 u 为起始点的边的编号,以此类推。

        以链式前向星的方法建图的最小生成树prim算法: (主要代码)

void addedge(int u,int v,int w)
{edge[++cnt].v=v;edge[cnt].next=head[u];edge[cnt].w=w;head[u]=cnt;
}
void prim(int s)
{memset(dis,0x3f,sizeof(dis)); // 初始化 memset(vis,0,sizeof(vis));dis[s]=0;q.push((node1){0,s});while(!q.empty()){int u=q.top().v;q.pop();if(vis[u]) continue;vis[u]=1;sum+=dis[u];for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].v;int w=edge[i].w;if(dis[v]>w){dis[v]=w;q.push((node1){w,v});}}}
}

四、三种方法的优缺点比较::

        1.邻接矩阵:

            邻接矩阵通过一个二维数组直接表示两点之间的权值,但是由于二维数组,容易出现空间空间的浪费,并且数据量大时会出现爆栈。

        2. 邻接链表(vector):

            通过STL,步骤简单,vector采用可变数组的方式,动态变化时会耗费额外时间复制数组。

        3.链式前向星:

           操作简单,但不容易理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/333301.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LINUX环境基础练习题(附带答案)

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

LLM提示工程的技巧

1. 从简单开始&#xff08;Start Simple&#xff09; 避免在一开始就增加太多的复杂性。 从简单的提示开始&#xff0c;然后在后续提示中添加更多信息和上下文。 这样&#xff0c;提示就是一个迭代过程&#xff0c;提示在此过程中进一步发展。 从简单的开始&#xff0c;就有足…

2024.05.27学习记录

1、面经复习&#xff1a; 实际工作经验章节 2、代码随想录刷题&#xff1a;动态规划剩下部分和单调栈 3、rosebush 组件库完成Input 和 AutoComplete部分内容

我的创作纪念日——我与CSDN一起走过的128天

目录 一、机缘&#xff1a;旅程的开始 二、收获&#xff1a;沿路的花朵 三、日常&#xff1a;不断前行中 四、成就&#xff1a;一点小确幸 五、憧憬&#xff1a;梦中的重点 一、机缘&#xff1a;旅程的开始 最开始开始写博客是在今年一二月份的时候&#xff0c;也就是寒假…

第十五届“北斗杯”全国青少年空天科技体验与创新大赛安徽赛区阜阳市解读会议

5月19日&#xff0c;第十五届“北斗杯”全国青少年空天科技体验与创新大赛安徽赛区阜阳解读活动在阜阳市图书馆隆重举行。共青团阜阳市委员会学少部副部长丁晓龙、阜阳市师范大学物理系副主任黄银生教授、安徽科技报阜阳站站长李伟、市人工智能学会秘书长郭广泽、“北斗杯”安徽…

kettle 读取记事本文件给java组件处理

kettle9.4 用到两个组件 文本文件输入 文件内容如下 文本文件输入---文件 文本文件输入---内容 注意事项&#xff1a;分隔符这里&#xff0c;我一直没注意&#xff0c;导致不管怎么读数据都读不到&#xff1b;可以用换行符&#xff0c;可以用其他的&#xff0c;视情况而定&…

Android Studio自带Profiler工具进行CPU资源及线程问题分析步骤

1、运行需要检测CPU资源问题与线程问题的程序 这里以“com.example.opengltest”程序为例。 2、点击Profiler按钮 3、点击SESIONS ""号按钮选择设备&#xff0c;选择对应设备下的应用或进程 4、双击CPU区块 5、选择Trace config选项&#xff0c;选择“Java/Kotli…

张大哥笔记:赚钱高手养成计划---如何将一份时间产生N份收入?

我们常说的赚钱的四种境界有哪些&#xff1f; 1.靠体力挣钱 2.靠技能挣钱 3.靠知识挣钱 4.靠平台钱生钱 所以对应的收入的模式就会是下面4种模式&#xff1a; 1.一份时间卖1次 2.一份时间卖N次 3.一份时间溢价卖N次 4.购买他人时间为自己所用 时间对于每个人都是相同的…

mail发送接口API如何使用?怎么调用接口?

mail发送接口API的性能怎么样&#xff1f;邮件接口发信的技巧&#xff1f; 为了自动化和集成电子邮件功能到应用程序或系统中&#xff0c;开发人员可以使用各种邮件发送接口API。AokSend将介绍如何使用这些API来发送电子邮件&#xff0c;提高效率和灵活性。 mail发送接口API&…

C++青少年简明教程:switch语句

C青少年简明教程&#xff1a;switch语句 在C中&#xff0c;switch语句用于基于一个表达式的值来执行不同的代码块。这个表达式通常是一个整数类型&#xff08;如int&#xff0c;char&#xff0c;或枚举类型&#xff09;&#xff0c;并且case标签必须是整数常量表达式。 语法格…

DRKCT复现

Osint 羡慕群友每一天 MISC 签到 扫码关注公众号&#xff0c;回复一下行 &#xff08;眼神要好&#xff0c; 我做题时没看见有个二维码&#xff09; 神秘的文字 把代码js运行一下 (用js的原因是前面给的动物代表的字符类似jsfuck代码) &#x13142;![]; &#x13080;!…

音视频开发5 补充 - Nginx搭建rtmp流媒体服务器,目的是让ffmpeg 可以直播推流

直播推流 ffmpeg -re -i out.mp4 -c copy flv rtmp://server/live/streamName -re, 表示按时间戳读取文件 参考&#xff1a; Nginx 搭建 rtmp 流媒体服务器 (Ubuntu 16.04) https://www.jianshu.com/p/16741e363a77 第一步 准备工作 安装nginx需要的依赖包 打开 ubutun 终端…

Less语言

Less是一门预编译语言&#xff0c;它扩展了CSS语言&#xff0c;增加了变量、Mixin、函数等特性&#xff0c;使CSS更易维护和扩展 Less也扩充了CSS语言&#xff0c;增加了诸如变量、混合运算、函数等功能。Less既可以运行在服务端(Node.js和Rhino平台)也可以运行在客户端(浏览器…

K8S认证|CKA题库+答案| 13. sidecar 代理容器日志

目录 13、使用 sidecar 代理容器日志 CKA v1.29.0模拟系统 下载试用 题目&#xff1a; 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、生成yaml文件 3&#xff09;、官网找模板 4&#xff09;、编辑yaml文件 5&#xff09;、应用yaml文件 ​6&…

H3CNE-8-ARP工作原理

ARP&#xff1a;Address Resolution Protocol 通过目的IP地址请求对方的MAC地址的过程。 数据链路层在进行数据封装时&#xff0c;需要目的MAC地址。 arp -a 查看 arp -d * 清空 主机A发送一个数据包给主机C之前&#xff0c;首先要获取C的MAC地址 数据封装

Day 40 Web容器-Tomcat

Tomcat 一&#xff1a;Tomcat简介 1.简介 ​ Tomcat是Apache软件基金会&#xff08;Apache Software Foundation&#xff09;的Jakarta 项目中的一个核心项目 ​ Tomcat服务器是一个免费的开放源代码的Web应用服务器&#xff0c;属于轻量级应用服务器 ​ Tomcat是WEB容器/WE…

Golang | Leetcode Golang题解之第108题将有序数组转换为二叉搜索树

题目&#xff1a; 题解&#xff1a; func sortedArrayToBST(nums []int) *TreeNode {rand.Seed(time.Now().UnixNano())return helper(nums, 0, len(nums) - 1) }func helper(nums []int, left, right int) *TreeNode {if left > right {return nil}// 选择任意一个中间位置…

诚心分享!主食冻干横向对比:希喂、爱立方、K9等谁最值得入手?

主食冻干到底有必要喂吗&#xff1f;七年铲龄铲屎官告诉你&#xff0c;是真的很有必要喂&#xff01; 这些年随着宠物经济的发展、科学养宠的普及&#xff0c;现在养猫不仅局限在让猫吃饱就行&#xff0c;更多人开始关注到猫的饮食健康。大量的实际喂养案例证明了&#xff0c;传…

冯喜运:5.27黄金短线看震荡,今日黄金原油走势分析

【黄金消息面分析】&#xff1a;黄金作为传统的避险资产&#xff0c;在经济不确定性中扮演着至关重要的角色。近期&#xff0c;国际黄金价格经历了显著的波动。从5月9日的低点2325.19美元/盎司反弹至2340美元/盎司以上&#xff0c;尽管金价曾一度触及2449.89美元/盎司的历史高点…

Baxter机器人摄像头打不开的一个可能的解决办法

操作过程 1.连上机器人 cd ros_ws/ ./baxter.sh2.查看摄像头&#xff08;最多开两个&#xff09; rosrun baxter_tools camera_control.py -l 3.打开指定的摄像头 rosrun baxter_tools camera_control.py -o left_hand_camera -r 1280x800 另&#xff1a;关闭的话 rosrun…