图的学习

news2024/9/21 16:43:33

图的基本概念和术语

图的定义:图是由顶点的有穷非空集合和顶点之间的边的集合组成的,G表示,V是图G中顶点的集合,E是图G中边的集合

无向图:任意两点的边都是无向边组成的图(无向边:(A,B)表示点A能到点B,点B也能到点A)

有向图:任意两点的弧都是有向边组成的图(有向边:<A,B>表示点A能到点B,点B不能到点A(B为弧头,A为弧尾)

边较少的图叫稀疏图,反之叫稠密图

权,网:图的边或弧相关的数叫权,这种带权的图通常叫做网

顶点的度:无向图中顶点的度表示和顶点相关联的的边的数目(记TD);有向图中分为入度和出度

 入度为顶点为弧头有关联的弧,出度为顶点为弧尾有关联的弧

路径长度:路径长度是路径上边或弧的数目

回路,环:第一个顶点和最后一个顶点相同的路径称为回路或环

连通图:图中任意两点都是连接的(有路径),有向图中称为强连通图

无向图中联通n个顶点和n-1条边叫生成树,有向图中一顶点入度为0其余顶点入度为1的叫有向树。

 

 

 图的储存结构

邻接矩阵

图的邻接矩阵采用顺序存储结构,用一个一维数组储存顶点的信息,一个二维数组储存图中边或弧的的信息

优点:便于理解,适合稠密图,O(1)判断两点是否有边,删除边比较方便

缺点:遇到边较少的图,浪费大量空间,图的建立,dfs,bfs遍历时间复杂度较高为O(N^2),删除点不方便

 邻接表

邻接表采用顺序+链式存储结构,一个一维结构体数组(数组大小为结点数量),结构体数组的存储元素构成单链表,每一个单链表链接与该结点相连的点

 优点:根据需求分配空间,浪费的空间较少,适合稀疏图

 缺点:删除边或点比较麻烦,对于有向图不利于求某个点出度的数量

 

 图的遍历

广度优先遍历和深度优先遍历,对于邻接矩阵和邻接表的时间复杂度都为平方阶和线性阶

 所以对于有关于图的遍历问题一般采用邻接表储存图,时间开销更小

图中如果不是联通图,存在一次遍历不能遍历全部的点,一般用数组标记判断点是否遍历

 模板题 洛谷 P5318 查找文献

本题考察图的深度和广度

题目描述

小 K 喜欢翻看洛谷博客获取知识。每篇文章可能会有若干个(也有可能没有)参考文献的链接指向别的博客文章。小 K 求知欲旺盛,如果他看了某篇文章,那么他一定会去看这篇文章的参考文献(如果他之前已经看过这篇参考文献的话就不用再看它了)。

假设洛谷博客里面一共有n(n≤10^5) 篇文章(编号为 1 到 n)以及 m(m≤10^6) 条参考文献引用关系。目前小 K 已经打开了编号为 1 的一篇文章,请帮助小 K 设计一种方法,使小 K 可以不重复、不遗漏的看完所有他能看到的文章。

这边是已经整理好的参考文献关系图,其中,文献 X → Y 表示文章 X 有参考文献 Y。不保证编号为 1 的文章没有被其他文章引用。

请对这个图分别进行 DFS 和 BFS,并输出遍历结果。如果有很多篇文章可以参阅,请先看编号较小的那篇(因此你可能需要先排序)。

输入格式

共 m+1 行,第 1 行为 2 个数,n 和 m,分别表示一共有 n(n≤10^5) 篇文章(编号为 1 到 n)以及m(m≤10^6) 条参考文献引用关系。

接下来 m 行,每行有两个整数 X,Y 表示文章 X 有参考文献 Y。

输出格式

共 2 行。 第一行为 DFS 遍历结果,第二行为 BFS 遍历结果。

输入输出样例

输入 #1

8 9
1 2
1 3
1 4
2 5
2 6
3 7
4 7
4 8
7 8

输出 #1

1 2 5 6 3 7 8 4 
1 2 3 4 5 6 7 8 

 看题发现本题的n的范围10^5用邻接矩阵不仅空间存不下,遍历也浪费时间,所以采用邻接表

这题不需要考虑是否为连通图,题目的数据,若是存在一个点与1号点没有联系则不需要输出这个点

思路

我们知道邻接表遍历结果不唯一的,而题目要求请先看编号较小的那篇(因此你可能需要先排序),链表不好进行排序,我们可以先对输入的m个x和y进行排序,因为对于邻接表一般采用头插法(先插入的点在链表的最后),按照y的比较进行降序排列,这样可以保证每一个单链表都是升序。

AC代码

#include<stdio.h>
#include<stdlib.h>
struct nb {
	int data;
    struct nb* p;
}a[100010];//邻接表
struct mm {
	int l, r;
}mr[1000010], b[1000010];//b为归并辅助数组
void guibin(int x, int y)//归并排序不多说
{
    if (x >= y) return;
    long long mid = (x + y) / 2, i, j;
    guibin(x, mid);
    guibin(mid + 1, y);
    int cnt = 0;
    for (i = x, j = mid + 1; i <= mid && j <= y;)
    {
        if (mr[i].r >= mr[j].r)
            b[++cnt] = mr[i++];
        else
            b[++cnt] = mr[j++];
    }
    while (i <= mid)
        b[++cnt] = mr[i++];
    while (j <= y)
        b[++cnt] = mr[j++];
    for (i = 1; i <= cnt; i++)
        mr[x + i - 1] = b[i];
}
int book[100010], book1[100010] = { 0 };//标记数组
void dfs(int  x)
{
    struct nb* gg;
    book[x] = 1;//第一次访问标记为1
    printf("%d ", x);//打印结果
    gg = a[x].p;
    while (gg)
    {
        if (book[gg->data] == 0)//第一次访问dfs搜索
            dfs(gg->data);
        gg = gg->p;
    }
}
void bfs(int x)
{
    int link[100010];
    int hard = 1, tail = 2;
    link[1] = x; book1[x] = 1;
    while (hard < tail)
    {
        printf("%d ", link[hard]);
        struct nb* f = a[link[hard]].p;
        while (f != NULL)
        {
            if (book1[f->data] == 0)
            {
                link[tail++] = f->data;
                book1[f->data] = 1;
            }
            f = f->p;
        }
        hard++;
    }
}
int main()
{
	int n, m, i, j;
    struct nb* q, * t, * s;
	scanf("%d %d", &n, &m);
	for (i = 1; i <= m; i++)//输入m个x,y
		scanf("%d %d", &mr[i].l, &mr[i].r);
    for (i = 1; i <= n; i++)
        a[i].p = NULL;
    guibin(1, m);//降序排序
    for (i = 1; i <= m; i++)//邻接表的建立
    {
        q = (struct nb*)malloc(sizeof(struct nb));
        q->data = mr[i].r; q->p = a[mr[i].l].p;
        a[mr[i].l].p = q;
    }
    dfs(1);//dfs搜索
    printf("\n");
    bfs(1);//bfs搜索
    for (i = 1; i <= n; i++)//清空邻接表链表,避免内存泄露
    {
        s = a[i].p;
        while (s != NULL)
        {
            t = s;
            s = s->p;
            free(t);
        }
    }
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java 的 Map 與 List

通過重新new 一個ArrayList 轉化 resTask.setList(new ArrayList<Group>(custMap.values())); 无序的Map List 有序的数据放到Map&#xff0c;就变成无序。 List排序 按照code 的字母进行排序A-Z resTask.getListData().sort(Comparator.comparing(Gmer::getCode));…

配置nginx作为静态文件托管服务器

下载nginx windows上是个压缩包 解压后, 使用命令行输入 nginx 进行启动 nginx -s stop 进行停止 nginx -s status 查看状态 可以配置一下环境变量 主要是配置文件, windows的nginx配置文件在 conf文件夹下 在http标签下 添加如下配置 其他地方不用更改,保持原样即可, 以…

[GN] 23种设计模式 —— 常见设计模式学习总结

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言创建型模式 —— 创建的艺术结构型模式 —— 组合的艺术适配器模式 -- 不兼容结构的协调对象适配器类适配器模式优缺点适用场景 组合模式 -- 树形结构的处理例子…

Springboot整合Websocket实现ws和wss连接

1. 引入pom依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><version>2.7.10</version> </dependency>2. 新建websocket配置文件 import org.springf…

ElementUI Form:Radio 单选框

ElementUI安装与使用指南 Radio 单选框 点击下载learnelementuispringboot项目源码 效果图 el-radio.vue 页面效果图 项目里el-radio.vue代码 <script> export default {name: el_radio,data() {return {radio: 1,radio2: 2,radio3: 3,radio4: 上海,radio5: 上海,ra…

【JAVA】单例模式的线程安全性

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 正文 我的其他博客 正文 老生常谈的问题了&#xff0c;首先要说的是单例模式的线程安全意味着&#xff1a;某个类的实例在多线程环境 下只会被…

Codeforces Round 922 (Div. 2) (A~B)

A. Brick Wall 读题不谨慎翻车半小时&#xff0c;警惕黑体加粗的单词&#xff0c;真的很重要。 给你n高&#xff0c;m宽的方框&#xff0c;往里面放 1*k 大小的砖头&#xff0c;k自己选&#xff0c;但是>2&#xff0c;塞满方框的情况并且不超出边界&#xff0c;输出最大的…

(M)UNITY三段攻击制作

三段攻击逻辑 基本逻辑&#xff1a; 人物点击攻击按钮进入攻击状态&#xff08;bool isAttack&#xff09; 在攻击状态下&#xff0c; 一旦设置的触发器&#xff08;trigger attack&#xff09;被触发&#xff0c;设置的计数器&#xff08;int combo&#xff09;查看目前攻击…

【计算机网络】网络的网络

网络的网络 客户 customer 接入ISP提供商 provider 全球承载ISP多个ISP的层级结构 第一层ISP &#xff08;tier-1 ISP &#xff09; 位于顶部 区域ISP &#xff08;reginal ISP&#xff09;Level 3通信 &#xff0c;AT&T&#xff0c;Sprint &#xff0c;NTT存在点&#x…

交叉注意力融合时域、频域特征的FFT + CNN-Transformer-CrossAttention轴承故障识别模型

目录 往期精彩内容&#xff1a; 前言 1 快速傅里叶变换FFT原理介绍 第一步&#xff0c;导入部分数据 第二步&#xff0c;故障信号可视化 第三步&#xff0c;故障信号经过FFT可视化 2 轴承故障数据的预处理 2.1 导入数据 2.2 制作数据集和对应标签 3 交叉注意力机制 …

【机器学习300问】21、什么是激活函数?常见激活函数都有哪些?

在我写的上一篇文章中介绍了感知机&#xff08;单个神经元&#xff09;的构成&#xff0c;其中就谈到了神经元会计算传送过来的信号的总和&#xff0c;只有当这个总和超过了某个界限值时&#xff0c;才会输出值。这也称为“神经元被激活”。如果想对神经网络是什么有更多了解的…

人工智能是哪个专业

人工智能是一个以计算机科学为基础&#xff0c;由计算机、心理学、哲学等多学科交叉融合的交叉学科、新兴学科。其研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学&#xff0c;企图了解智能的实质&#xff0c;并生产出一种新的能以人类…

机器学习——绪论总结

目录 一、引入 二、基本术语 三、假设空间与归纳偏 四、模型选择 一、引入 机器学习&#xff1a;通过计算手段&#xff0c;得出具有能够自我修改、完善能力的模型&#xff0c;利用经验改善系统自身性能。算法使用数据得到模型的过程即称为学习&#xff0c;或训练 流程&…

uni-app app引入天地图

话不多说咸鱼来了 <template><view><div class"mapBox" style"width: 100%; height: 100vh;background: #ddc0c0;" id"mapId" ></div></view> </template> <script module"test" lang"r…

vue使用antv-x6 绘制流程图DAG图(二)

代码&#xff1a; <template><div class"graph-wrap" click.stop"hideFn"><Toobar :graph"graph"></Toobar><!-- 小地图 --><div id"minimap" class"mini-map-container"></div>…

Security ❀ TCP异常报文详解

文章目录 1. TCP Out-Of-Order2. TCP Previous Segment Lost3. TCP Retransmission4. TCP Dup Ack XXX#X5. TCP Windows Update6. TCP Previous segment not captured7. 异常案例分析 TCP协议中seq和ack seq的联系&#xff1a; id4的http请求报文由客户端发向服务器&#xff0…

C++ 数论相关题目 台阶-Nim游戏

现在&#xff0c;有一个 n 级台阶的楼梯&#xff0c;每级台阶上都有若干个石子&#xff0c;其中第 i 级台阶上有 ai 个石子(i≥1 )。 两位玩家轮流操作&#xff0c;每次操作可以从任意一级台阶上拿若干个石子放到下一级台阶中&#xff08;不能不拿&#xff09;。 已经拿到地面…

JAVA处理类似饼状图占比和100%问题,采用最大余额法

前言&#xff1a; 在做数据统计报表的时候&#xff0c;有两种方式解决占比总和达不到100%或者超过100%问题。 第一种方式是前端echart图自带的算分框架。 第二种方式是java后端取处理这个问题。 现存问题&#xff1a; 前端通过饼状图的方式去展示各个分类的占比累加和为100%问题…

vue前端页面时间显示问题解决方法

解决方法&#xff0c; <template slot-scope"scope"><span>{{ parseTime(scope.row.boxClosingOnlineTime, {y}-{m}-{d} {h}:{i}:{s}) }}</span> </template> 刷新页面&#xff1a; 此外&#xff0c;使用JsonFormat(pattern "yyyy-M…

Kaggle竞赛系列_SpaceshipTitanic金牌方案分析_数据分析

文章目录 【文章系列】【前言】【比赛简介】【正文】&#xff08;一&#xff09;数据获取&#xff08;二&#xff09;数据分析1. 缺失值2. 重复值3. 属性类型分析4. 类别分析5. 分析目标数值占比 &#xff08;三&#xff09;属性分析1. 对年龄Age分析&#xff08;1&#xff09;…