数据结构-图的应用

最小生成树(最小代价树)

对于一个带权连通无向图G=(V,E),生成树不同,每棵树的权(即树中所有边上的权值之和)也可能不同。设R为G的所有生成树的集合,若T为R中边的权值之和最小的生成树,则T称为G的最小生成树(Minimum-Spanning-Tree, MST)。
image.png

  • 最小生成树可能有多个,但边的权值之和总是唯一且最小的

  • 最小生成树的边数=顶点数一1。砍掉一条则不连通,增加一条边则会出现回路

  • 如果一个连通图本身就是―棵树,则其最小生成树就是它本身

  • 只有连通图才有生成树,非连通图只有生成森林

Prim算法(普里姆)

Prim 算法(普里姆):
从某一个顶点开始构建生成树;
每次将代价最小的新顶点纳入生成树,
直到所有顶点都纳入为止。
image.png
image.png
3+5+1+4+2=15
image.png
时间复杂度:O(|V|2次方)
适合用于边稠密图

Kruskal算法(克鲁斯卡尔)

Kruskal算法(克鲁斯卡尔)
每次选择一条权值最小的边,使这条边的两头连通(原本已经连通的就不选)
直到所有结点都连通
image.png
时间复杂度:O(|E|log|E|)
适合用于边稀疏图

Prim算法的实现思想

image.png
image.png

更新还没加入的各个顶点的lowCast值
image.png

第二轮:
image.png
更新还没加入的各个顶点的lowCast值
image.png
image.png
第3轮:
image.png
image.png
第4轮:
image.png
image.png
第5轮:
image.png
image.png

Kruskal算法的实现思想

初始︰将各条边按权值排序
image.png
第1轮:检查第1条边的两个顶点是否连通(是否属于同一个集合)
第2轮︰检查第2条边的两个顶点是否连通(是否属于同一个集合)
第3轮︰检查第3条边的两个顶点是否连通(是否属于同一个集合)
第4轮︰检查第4条边的两个顶点是否连通(是否属于同一个集合)
第5轮︰检查第5条边的两个顶点是否连通(是否属于同一个集合)

每轮判断两个顶点是否属于同一集合

最短路径问题

image.png
“G港”是个物流集散中心,经常需要往各个城市运东西,怎么运送距离最近?
–单源最短路径问题
各个城市之间也需要互相往来,相互之间怎么走距离最近?
–每对顶点间的最短路径

单源最短路径–BFS算法(无权图)、Dijkstra算法(带权图、无权图)
各顶点间的最短路径–Floyd算法(带权图、无权图)

BFS求无权图的单源最短路径
image.png

bool visited[MAX_VERTEX_NUM];//访问标记数组
//广度优先遍历
void BFS(Graph G,int v){//从顶点v出发,广度优先遍历图G
	visit(v);			//访问初始顶点v
    visited[v]=TRUE;	//对v做已访问标记
    Enqueue(Q,v);		//顶点v入队列Q
    while(!isEmpty(Q)){
        DeQueue(Q,v);	//顶点v出队列
        for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w))
            //检测v所有邻接点
            if(!visited[w]){	//w为v的尚未访问的邻接顶点
                visit(w);		//访问顶点w
                visited[w]=TRUE;//对w做已访问标记
                EnQueue(Q,w);	//顶点w入队列
            }
    }
}
//求顶点u到其他顶点的最短路径
void BFS_MIN_Distance(Graph G,int v){//从顶点v出发,广度优先遍历图G
	//d[i]表示从v到i结点的最短路径
    for(i=0;i<G.vexnum;++i){
        d[i]=; //初始化路径长度
        path[i]=-1;//最短路径从哪个顶点过来
    }
    d[u]=0;
    visited[v]=TRUE;	//对v做已访问标记
    Enqueue(Q,v);		//顶点v入队列Q
    while(!isEmpty(Q)){
        DeQueue(Q,v);	//顶点v出队列
        for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w))
            //检测v所有邻接点
            if(!visited[w]){	//w为v的尚未访问的邻接顶点
                d[w]=d[v]+1//路径长度加1
                path[w]=u;		//最短路径应从v到w
                visited[w]=TRUE;//对w做已访问标记
                EnQueue(Q,w);	//顶点w入队列
            }
    }
}

image.pngimage.png

最短路径问题-Dijkstra算法

Dijkstra算法
image.png
image.png
image.png
检查所有邻接自Vi的顶点,若其final值为false,则更新dist和path信息
image.png
image.png

image.png
检查所有邻接自Vi的顶点,若其final值为false,则更新dist和path信息
image.png
image.png
image.png
image.pngimage.png
V0到V2的最短(带权)路径长度为:dist[2]=9
通过path[ ]可知,V0到V2的最短(带权)路径:V0->V4->V1->V2
Dijkstra算法不适用于有负权值的带权图

最短路径-Floyd算法

Floyd算法:求出每一对顶点之间的最短路径
image.png
image.png
image.png
#0:若允许在V0中转,最短路径是?
image.png
image.png
#1:若允许在V0、V1中转,最短路径是?
image.png
image.png
#2:若允许在V0、V1、V2中转,最短路径是?
image.png
image.png
image.png
Floyd算法核心代码
image.png

//....准备工作,根据图的信息初始化矩阵A和path
for(int k=0;k<n;k++){		//考虑以Vk作为中转点
	for(int i=0;i<n;i++){	//遍历整个矩阵,i为行号,j为列号
        for(int j=0;j<n;j++){
            if(A[i][j]>A[i][k]+A[k][j]){//以Vk为中转点的路径更短
                A[i][j]=A[i][k]+A[k][j];//更新最短路径长度
                path[i][j]=k;			//中转点
            }}
    }
}

Floyd算法不能解决带有“负权回路”的图(有负权值的边组成回路),这种图有可能没有最短路径
image.png
image.png

有向无环图描述表达式

有向无环图:若一个有向图中不存在环,则称为有向无环图,简称DAG图
image.png
Step4:从底向上逐层检查同层的运算符是否可以合体
image.png

拓扑排序

AOV网
AOV网(Activity On Vertex NetWork,用顶点表示活动的网)
用DAG网(有向无环图)表示一个工程。顶点表示活动,有向边<Vi,Vj>表示活动Vi必须先语活动Vj进行
image.png
拓扑排序
image.png
拓扑排序的实现:
1:从AOV网中选择一个没有前驱(入度为0)的顶点并输出
2:从网中删除该顶点和所有以它为起点的有向边
3:重复1和2直到当前的AOV网为空或当前网中不存在无前驱的顶点为止
image.png

#define MaxVertexNum 100 //图中顶点数目的最大值
typedef struct ArcNode{  //边表结点
	int adjvex;		//该弧所指向的顶点的位置
    struct ArcNode *nextarc;	//指向下一条弧的指针
}ArcNode;
typedef struct VNode{	//顶点表结点
	VertexType data;	//顶点信息
    ArcNode *firstarc;	//指向第一条依附该顶点的弧的指针
}VNode,AdjList[MaxVertexNum];
typedef struct{
    AdjList vertices;	//邻接表
    int vexnum,arcnum;	//图的顶点数和弧数
}Graph;		//Graph是以邻接表存储的图类型
bool TopologicalSort(Graph G){
	InitStack(S);	//初始化栈,存储入度为0的顶点
    for(int i=0;i<G.vexnum;i++)
        if(indegree[i]==0)
            Push(S,i);	//将所有入度为0的顶点进栈
    int count=0;		//计数,记录当前已经输出的顶点数
    while(!isEmpty(S)){	//栈不空,则存在入度为0的顶点
        Pop(S,i);	//栈顶元素出栈
        print[count++]=i;	//输出顶点i
        for(p=G.vertices[i].firstarc;p;p=p->nextarc){
        	//将所有i指向的顶点的入度减1,并且将入度减为0的顶点压入栈s
            v=p->adjvex;
            if(!(--indegree[v]))
                Push(S,v);	//入度为0,则入栈
        }
    }
    if(count<G.vexnum)
        return false;	//排序失败,有向图中有回路
    else 
        return true;	//拓扑排序成功
}

逆拓扑排序的实现(DFS算法)

void DFSTraverse(Graph G){	//对图G进行深度优先遍历
	for(v=0;v<G.vexnum;++v)	
        visited[v]=FALSE;	//初始化已访问标记数据
    for(v=0;v<G.vexnum;++v)	//本代码中是从v=0开始遍历
        if(!visited[v])
            DFS(G,v);
}
void DFS(Graph G,int v){//从顶点v出发,深度优先遍历图G
	visited[v]=TRUE;	//设已访问标记
    for(w=FirstNeighbor(G,v);w>=0;w=NextNeighor(G,v,w))
        if(!visited[w]){	//w为u的尚未访问的邻接顶点
        DFS(G,w);
        }
    print(v);//输出顶点
}

关键路径

AOE网
在带权有向图中,以顶点表示事件,以有向边表示活动,以边上的权值表示完成该活动的开销(如完成活动所需的时间),称之为用边表示活动的网络,简称AOE网(Activity On Edge NetWork)
image.png
AOE网具有以下两个性质:
1:只有在某顶点所代表的事件发生后,从该顶点出发的各有向边所代表的活动才能开始
2:只有在进入某顶点的各有向边所代表的活动都已结束时,该顶点所代表的事件才能发生。
另外,有些活动是可以并行进行的。
image.png

从源点到汇点的有向路径可能有多条,所有路径中,具有最大路径长度的路径称为关键路径,而把关键路径上的活动称为关键活动
完成整个工程的最短时间就是关键路径的长度,若关键活动不能按时完成,则整个工程的完成时间就会延长
image.png
求关键路径的步骤
image.png
求所有事件的最早发生时间
image.png
求所有事件的最迟发生时间
image.png
求所有活动的最早发生时间
image.png
求所有活动的最迟发生时间
image.png
求所有活动的时间余量
image.png
关键活动:a2、a5、a7
关键路径:V1->V3->V4->V6
关键活动、关键路径的特性
若关键活动耗时增加,则整个过程的工期将增长
缩短关键活动的时间,可以缩短整个工程的工期
当缩短到一定程度时,关键活动可能会变成非关键活动
可能有多条关键路径,只提高一条关键路径上的关键活动速度并不能缩短整个工程的工期,只有加快那些包括在所有关键路径上的关键活动 才能达到缩短工期的目的

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

商城免费搭建之java商城 java电子商务Spring Cloud+Spring Boot+mybatis+MQ+VR全景+b2b2c

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

工业级环网交换机:高效过滤和转发数据包的网络设备

环形网络是一种网络拓扑结构&#xff0c;其特点是将每个设备连成一个连续的环形。它可以确保一台设备发出的信号可以被环上所有其他设备接收到。环网冗余是指工业级环网交换机是否能够应对网络线缆连接中断的情况。当出现连接中断时&#xff0c;工业级环网交换机会接收到此消息…

常见排序算法之快速排序

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法。 基本思想为∶任取待排序元素序列中的某元素作为基准值&#xff0c;按照该排序码将待排序集合分割成两子序列&#xff0c;左子序列中所有元素均小于基准值&#xff0c;右子序列中所有元素均大于基准值&#xff0c;…

【Pytest】跳过执行之@pytest.mark.skip()详解

一、skip介绍及运用 在我们自动化测试过程中&#xff0c;经常会遇到功能阻塞、功能未实现、环境等一系列外部因素问题导致的一些用例执行不了&#xff0c;这时我们就可以用到跳过skip用例&#xff0c;如果我们注释掉或删除掉&#xff0c;后面还要进行恢复操作。 1、skip跳过成…

nodejs express multer 保存文件名为中文时乱码,问题解决 originalname

nodejs express multer 保存文件名为中文时乱码&#xff0c;问题解决 originalname 一、问题描述 用 express 写了个后台&#xff0c;在接收文件并保存的时候 multer 接收到的文件名为乱码。 二、解决 找了下解决方法&#xff0c;在 github 的 multer issue 中找到了答案 参…

【MySQL进阶之路丨第十七篇(完结)】一文带你精通MySQL运算符

引言 在上一篇中我们介绍了MySQL函数&#xff1b;在开发中&#xff0c;对MySQL运算符的运用是十分重要的。这一篇我们使用命令行方式来帮助读者掌握MySQL中运算符的操作。 上一篇链接&#xff1a;【MySQL进阶之路丨第十六篇】一文带你精通MySQL函数 MySQL运算符 MySQL中的运…

node插件MongoDB(四)—— 库mongoose 的个性话读取(字段筛选、数据排序、数据截取)(四)

文章目录 一、字段筛选二、数据排序三、数据截取1. skip 跳过2. limit 限定![在这里插入图片描述](https://img-blog.csdnimg.cn/c7067b1984ee4c6686f8bbe07cae9176.png) 一、字段筛选 字段筛选&#xff1a;只读取指定的数据&#xff0c;比如集合&#xff08;表&#xff09;中有…

JMeter 相关的面试题

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;加入1000人软件测试技术学习交流群&#x1f4e2;资源分享&#xff1a;进了字节跳动之后&#xff0c;才…

【已验证】php配置连接sql server中文乱码(解决方法)更改utf-8格式

解决数据库中的中文数据在页面显示乱码的问题 在连接的$connectionInfo中设置"CharacterSet" > "UTF-8"&#xff0c;指定编码方式即可 $connectionInfo array("UID">$uid, "PWD">$pwd, "Database">$database…

提升采购订单管理效率的五个最佳实践

企业每年都要订购成千上万的商品和服务。公司运营和发展所需的一切都来自庞大的供应商网络&#xff0c;而沟通这些需求的主要方式是通过采购订单。 由于所有订单都会流经系统&#xff0c;而且每个月都会发生数千元不等的供应支出&#xff0c;因此掌握采购订单流程成为重中之重…

[autojs]逍遥模拟器和vscode对接

第一步&#xff1a;启动autojs服务 第二步&#xff1a;去cmd查看ip地址&#xff0c;输入ipconfig 第三步&#xff1a;打开逍遥模拟器中的sutojs-左上角- 连接电脑&#xff0c;然后输入WLAN或者其他ip也行&#xff0c;根据自己电脑实际情况确认 此时vscode显示连接成功。我们写…

selenium 自动化测试 1-如何搭建自动化测试环境,搭建环境过程应该注意的问题

最近也有很多人私下问我&#xff0c;selenium学习难吗&#xff0c;基础入门的学习内容很多是3以前的版本资料&#xff0c;对于有基础的人来说&#xff0c;3到4的差别虽然有&#xff0c;但是不足以影响自己&#xff0c;但是对于没有学过的人来说&#xff0c;通过资料再到自己写的…

Pinia 是什么?Redux、Vuex、Pinia 的区别?

结论先行&#xff1a; Pinia 是 Vue 官方团队开发的一个全新状态管理库。核心都是解决组件间的通信和数据的共享问题。 它和 Vuex 的区别呢&#xff0c;一个是虽然它和 Vuex 类似&#xff0c;但 Pinia 使用起来更加简单和直观。因为 Pinia 基于 Vue3 的组合式 API 风格&…

【Unity】零基础实现塔防游戏中敌人沿固定路径移动的功能

目录 场景搭建 烘焙(Bake) 敌人动作控制 脚本实现 我们知道&#xff0c;在一些塔防小游戏中&#xff0c;敌人往往会沿着给定的一条路径移动&#xff0c;我们在条路的路边会布置防御设施&#xff0c;攻击消灭敌人&#xff0c;阻止敌人到达终点。 场景搭建 我们首先新建一个…

【数据结构与算法】DFA算法-关键词匹配-java案例实现

该算法往往是用于匹配一些敏感词、绝对词等&#xff0c;从一篇文章中快速找到其中包含的关键词。 实现思路&#xff1a; 先读取所有关键词并存入set集合中。再将set中的关键词存入HashMap中&#xff0c;是以每个关键词字顺序存储&#xff0c;key为一个字、value为一个HashMap。…

Laplacian Redecomposition for Multimodal Medical Image Fusion

LRD方法 GDIE means ‘gradient-domain image enhancement’&#xff0c;DGR means ‘decision graph redecomposition’ MLD means ‘maximum local difference’ LEM means ‘local energy maximum’&#xff0c;OD means ‘overlapping domain’&#xff0c;LP means ‘L…

Awesome-Selfhosted:互联网常见服务开源平替 | 开源日报 No.68

awesome-selfhosted/awesome-selfhosted Stars: 137.7k License: NOASSERTION Awesome-Selfhosted 是一个列出了可以在自己的服务器上托管的免费软件网络服务和 Web 应用程序列表。 以下是该项目的主要功能&#xff1a; 提供各种类型 (如分析、备份、博客平台等) 的开源软件…

Vue创建浅层响应式数据

shallowReactive&#xff1a;只处理对象第一层数据的响应式&#xff08;浅响应式&#xff09;。 shallowRef&#xff1a;只处理基本数据类型的响应式&#xff0c;不处理对象类型的响应式。 shallowReactive 适用于&#xff1a;如果有一个对象类型的数据&#xff0c;结构比较深…

SQL表、字段、查询参数获取

SQL工具类表、字段、查询参数提取 1. 执行效果2. 使用2.1 引入依赖2.2 相关实体2.3 工具类 1. 执行效果 2. 使用 2.1 引入依赖 <!-- sql 解析处理--><dependency><groupId>com.github.jsqlparser</groupId><artifactId>jsqlparser</artifact…

PLSQL工具 数据库连接名的设置

在help >>surpost info 能看到 这东西好难用啊。。不直接显示url,非要搞个名称。。