C语言-数据结构-图

目录

一,图的概念

1,图的定义

2,图的基本术语

二,图的存储结构

1,邻接矩阵

2,邻接表

三,图的遍历

1,深度优先搜索

2,广度优先搜素

四,生成树和最小生成树

1,生成树的特点:

2,最小生成树

(1)普利姆算法Prim

(2)普里姆算法思路

五,最短路径

1,Dijkstra算法

2,Floyd算法

六,拓扑排序

七,关键路径


一,图的概念

1,图的定义

在图G中,如果代表边的顶点对是无序的,则称G为无向图。用圆括号 序偶表示无向边。
如果表示边的顶点对是有序的,则称G为有向图。用尖括号序偶表示 有向边。

2,图的基本术语

1,端点和连接点无向图:若点若 存在一条边(i,j) 顶点i和顶点j为端点,它们互为邻接
有向图:若 存在一条边<i,j> 顶点i为起始端点(简称为起点), 顶点j为终止端点(简称终点),它们互为邻接点。
2,顶点的度、入度和出度无向图:以顶点  i为端点的边数称为该顶点的度。
有向图: 以顶点i为终点的入边的数目,称为该 顶点的入度。以顶点i为始点的出边的数目,称为该顶点的出度。一个顶点的入度与出度的和为该顶点的度。
3、完全图无向图:每 两个顶点之间都存在着一条边,称为完全无向图,包含有 n(n-1)/2条边。
有向图:每 两个顶点之间都存在着方向相反的两条边,称为完全有向 图,包含有n(n-1)条边。
4、子图设有两个图G=(V,E)和G'=(V',E'),若V'是V的子集, 且E'是E的子集,则称G'是G的子图。
5, 路径长度路径长度是指一条路径上经过的边的数目。
6,简单路径若一条路径上除开始点和结束点可以相同外,其余顶点均不相同,则称 此路径为简单路径。
7、回路或环若一条路径上的开始点与结束点为同一个顶点,则此路径被称为回 路或环。开始点与结束点相同的简单路径被称为简单回路或简单环。
8、连通、连通图和连通分量

无向图:

(1)若从顶点i到顶点j有路径,则称顶点i和j是连通的。

(2)若图中任意两个顶点都连通,则称为连通图,否则称为非连通图。

(3)无向图G中的极大连通子图称为G的连通分量。显然,任何连通图的连 通分量只有一个,即本身,而非连通图有多个连通分量。

有向图:

(1)若从顶点i到顶点j有路径,则称从顶点i到j是连通的。

(2)若图G中的任意两个顶点i和j都连通,即从顶点i到j和从顶点j到i都存在 路径,则称图G是强连通图。

(3)有向图G中的极大强连通子图称为G的强连通分量。显然,强连通图 只有一个强连通分量,即本身。非强连通图有多个强连通分量。

9、权和网图中每一条边都可以附带有一个对应的数值,这种与边相关的数 值称为权。边上带有权的图称为带权图,也称作网。

寻找非强连通图的强连通分量:

① 在图中找有向环。

② 扩展该有向环:如果某个顶点到该环中任一顶点有路径,并且该环 中任一顶点到这个顶点也有路径,则加入这个顶点。

二,图的存储结构

1,邻接矩阵

(1)如果G是无向图,则: A[i][j]=1:若(i,j)∈E(G) 0:其他
(2)如果G是有向图,则: A[i][j]=1:若∈E(G) 0:其他
(3)如果G是带权无向图,则: A[i][j]= wij :若i≠j且(i,j)∈E(G) 0:i=j ∞:其他
(4)如果G是带权有向图,则: A[i][j]= wij :若i≠j且∈E(G) 0:i=j ∞:其他

结论:无向图的邻接矩阵是对称的,顶点i的度=第i行(列)中1的个数

特别:完全图的邻接矩阵中,对角线元素为0,其余元素为1

结论:有向图的邻接矩阵可能是不对称的,顶点的出度=第i行元素之和;顶点的入度=第i列元素之和

邻接矩阵的存储需要用到两个表,一个表位顶点表,用一维数组表示,里面存储顶点.第二个表表示邻接矩阵,用二维数组表示

#define MAXInt 32767 //表示无穷大
#define MVNum 100  //最大顶点数
typedef char VerTexType;//顶点的数据类型为char
typedef int ArcType;//设置边的权值为整型typedef struct {VerTexType vexs[MVNum];//顶点表ArcType arcs[MVNum][MVNum];//邻接矩阵int vexnum, arcnum; //图当前的顶点数和边数
}AMGraph;

无网图初始化:

//无向网
Status CreateUDN(AMGraph &G)
{                                       //采用邻接矩阵表示法,创建无向网G 
cin>>G.vexnum>>G.arcnum;                //输入总顶点数,总边数 for(i =0; i<G.vexnum; ++i) cin>>G.vexs[i];                     //依次输入点的信息 for(i = 0; i<G.vexnum;++i)             //初始化邻接矩阵 for(j=0;j<G.vexnum;++j) G.arcs[i][j] = Maxlnt;         //边的权值均置为极大值 for(k = 0; k<G.arcnum;++k)
{                                        //构造邻接矩阵 cin>>v1>>v2>>w;                     //输入一条边所依附的顶点及边的权值 i = LocateVex(G, v1);j = LocateVex(G, v2);                 //确定v1和v2在G中的位置 G.arcs[i][j]=W;                         //边<v1,v2>的权值置为w G.arcs[j][i]= G.arcs[i][j];         //置<v1, v2>的对称边<v2,v1>的权值为w 
} return OK; 
}

邻接矩阵的主要特点:

一个图的邻接矩阵表示是唯一的。
特别适合于稠密图的存储。邻接矩阵的存储空间为O(n2)
优点:只管,简单,好理解,方便寻找任意两顶点之间是否存在边,方便计算顶点的度
缺点:不便于增加和删除顶点,如果为稀疏图,就会有大量的无效元素,浪费空间;统计边数,浪费时间

2,邻接表

分为两种节点,一种是头节点,头节点分为两个部分一部分是顶点信息,另一部分是指向第一条依附于该顶点的边的指针.边节点,第一部分是该边所指向的顶点的位置,第二部分是指向下一条边的指针,第三部分是边的相关信息,例如权,顶点,按照编号的顺序将顶点数据储存在一维数组中,相关联的的边,用线性链表进行连接

无向图:

邻接表并不唯一,边节点的顺序不唯一,若无向图有n个顶点,e条边,则邻接表需要n个头节点和2e个边节点,所以空间复杂度为O(n+2e)

无向图中的顶点v1的度为第i个单链表中的节点数

有向图:如果为邻接表,那么头节点指向的是该顶点的出度边,逆邻接表头节点指向的是该顶点的入度边.

由此,邻接表出度为第i单链表中的节点数,找出度容易,找入度难需要遍历整个图才可知. 逆邻接表入度为第i单链表中的节点数,找入度容易,出度困难

有向图和网空间复杂度为O(n+e)

#define MVNum 100  //最大顶点数typedef struct VNode {VerTexType deta;ArcNode* firstarc;
}VNode,AdjList[MVNum];typedef int OtherInfo;typedef struct ArcNode {  //边节点int adjvex;  //该边所指向的顶点的位置struct ArcNode* nextarc;//指向下一条边的指针OtherInfo info;//和边相关的信息,例如:权
}ArcNode;
typedef struct {AdjList vertices;int vexnum, arcnum;//图当前的顶点数和边数
}ALGraph;

无向网的初始化:

//无向图
Status CreateUDG(ALGraph &G){      //采用邻接表表示法,创建无向图G 
cin>>G.vexnum>>G.arcnum;           //输入总顶点数,总边数 for(i = 0; i<G.vexnum; ++i)       //输入各点,构造表头结点表
{ cin>> G.vertices[i].data;         //输入顶点值G.vertices[i].firstarc=NULL;
}for(k = 0; k<G.arcnum;++k){ cin>>V1>>v2;                    //输入一条边依附的两个顶点i = LocateVex(G, v1); j = LocateVex(G, v2);p1=new ArcNode;                 //生成一个新的边结点*p1p1->adjvex=j;                     //邻接点序号为j p1->nextarc=G.vertices[i].firstarc; G.vertices[i].firstarc=p1;     //将新结点*p1插入顶点vi的边表头部p2=new ArcNode;                 //生成另一个对称的新的边结点*p2->adjvex=i;                     //邻接点序号为i p2->nextarc= G.vertices[j].firstarc; G.vertices[j].firstarc=p2;         //将新结点*p2插入顶点vj的边表头部
}

邻接表的主要特点:

优点:方便找任意顶点的邻接点,节约稀疏图的空间,需要有向图:(n+e),无向图:(n+2e)的空间 
缺点:有向图,不方便统计度的总数
联系:
邻接表中的一行对应邻接矩阵中的一行,邻接表中的节点个数等于邻接矩阵中一行非零元素的个数
区别:
邻接矩阵空间复杂度为O(n^2),邻接表的空间复杂度为O(n+1)
邻接矩阵是唯一的,但是邻接表不是唯一的
邻接矩阵适用于稠密图,邻接表适用于稀疏图

三,图的遍历

1,深度优先搜索

■在访问图中某一起始顶点 v后,由 v出发,访问它的任一邻接顶点 w;

■再从 w 出发,访问与 w邻接但还未被访问过的顶点 W2;

■然后再从 w2出发,进行类似的访问,…

■ 如此进行下去,直至到达所有的邻接顶点都被访问过的顶点 u 为止。

■ 接着,退回一步,退到前一次刚访问过的顶点,看是否还有其它没有被访问的邻接顶点。

■ 如果有,则访问此顶点,之后再从此顶点出发,进行与前述类似的访问;

■如果没有,就再退回一步进行搜索。重复上述过程,直到连通图中 搜索 所有顶点都被访问过为止。

创建一个visited数组,用来储存该顶点是否被访问过:visited[i]=0表示顶点i没有访问;visited[i]=1表示顶点i已经访问过。

void DFS (AMGraph G,int v)
{cout<<v;visitd[v]=true;for(w=0;w<G.vexnum;W++){if(G.arcs[v][w]!=0&&(!visited[w]))DFS(G,w);}

邻接矩阵来扫描时间复杂度为O(n^2)

void DFS(ALGraph *G,int v){ArcNode *p; int w;visited[v]=1;                     //置已访问标记printf("%d ",v);                //输出被访问顶点的编号p=G->Adjlist[v].firstarc;        //p指向顶点v的第一条边的边头节点while (p!=NULL){w=p->adjvex;if (visited[w]==0)DFS(G,w);                  //若w顶点未访问,递归访问它p=p->nextarc;                  //p指向顶点v的下一条边的边头节点}}

邻接表来扫描,时间复杂度为O(n+e)

2,广度优先搜素

方法:从图的某一结点出发,首先依次访问该结点的所有邻点 Vi, Vib, …, Vi,再按这些顶点被访问的先后次序依次访问与它们相邻接的所有未被访问的顶点 重复此过程,直至所有顶点均被访问为止。

邻接表的BFS算法:

void BFS(ALGraph *G,int v){ArcNode *p; int w,i;int queue[MAXV],front=0,rear=0;     //定义循环队列int visited[MAXV];for (i=0;i<G->n;i++)visited[i]=0;                     //访问标志数组初始化printf("%2d",v);                        //输出被访问顶点的编号visited[v]=1;                        //置已访问标记rear=(rear+1)%MAXV;queue[rear]=v;//v进队while (front!=rear)                 //队列不空时循环{front=(front+1)%MAXV;w=queue[front];//出队并赋给wp=G->adjlist[w].firstarc;         //找w的第一个的邻接点while (p!=NULL){if (visited[p->adjvex]==0){printf(“%2d”,p->adjvex);     //访问之visited[p->adjvex]=1;rear=(rear+1)%MAXV;     //相邻顶点进队queue[rear]=p->adjvex;}p=p->nextarc;}}}

DFS算法和BFS算法比较:

空间复杂度相同,都是O(n)前者借用了堆栈,后者借用了队列
时间复杂度只与存储结构(邻接矩阵/邻接表)有关,与搜索路径无关

四,生成树和最小生成树

1,生成树的特点:

一个图有许多不同的生成树

生成树的顶点树与图的顶点数相同

生成树是图的极小连通子图,去掉一条边则非连通,再加一条边必然形成回路
有n个顶点的连通图的生成树有n-1条边
生成树中任意两个顶点之间的路径是唯一的

深度优先生成树/广度优先生成树

广度优先生成树高度 ≤ 深度优先生成树高度

2,最小生成树

对于带权连通图G,其中权 值之和最小的生成树称为图的最小生成树。最小生成树可能不唯一.

(1)普利姆算法Prim

初始化U={v}。v到其他顶点的所有边为候选边;重复以下步骤n-1次,使得其他n-1个顶点被加入到U中: 从候选边中挑选权值最小的边输出,设该边在V-U中的顶点是k,将 k加入U中;考察当前V-U中的所有顶点j,修改候选边:若(j,k)的权值小于原来和顶点k关联的候选边,则用(k,j)取代后者作为候选边。

(2)克鲁斯卡尔算法

设连通网 N=(V,E),令最小生成树初始状态为只有 n个顶点而无边的非连通图7=(V, ()),每个顶点自成一个连通分量。 在E中选取代价最小的边,若该边依附的顶点落在 T中不同的连通分量上(即:不能形成环)则将此边加入到T中;否则,舍去此边,选取下一条代价最小的边。 依此类推,直至7中所有顶 寿島大 点都在同一连通分量上为止。

普利姆算法克鲁斯卡尔算法
算法思想选择点选择边
时间复杂度O(n^2)O(elog2e)
适应范围稠密图稀疏图

五,最短路径

从源点到终点可能不止一条路径,把路径长度最短的那条路径 称为最短路径。

1,Dijkstra算法

1,单源最短路径(Dijkstra算法)

1.初始化:先找出从源点v0到各终点vk的直达路径(Vo.Vk), 即通过一条弧到达的路径。

2.选择:从这些路径中找出一条长度最短的路径(Vo,u)。

3更新:然后对其余各条路径进行适当调整: 若在图中存在弧(u,vk),且(Vo,U)+(U.Vk)<(Vo,Vk), 则以路径(Vo,u,Vk)代替(Vo.v)。 在调整后的各条路径中,再找长度最短的路径, 依此类推。

按长度递增的顺序求出图的某顶点到其余顶点的最短路径

时间复杂度:O(n2)

2,Floyd算法

所有顶点间的最短路径(Floyd算法)

逐个顶点试探,从vi到vj的所以可能存在的路径中选出一条最短路径

时间复杂度:O(n3)

六,拓扑排序

设G=(V,E)是一个具有n个顶点的有向图(AOV/AOE),V中顶点序列v1 , v2 ,…,vn 称为一个拓扑序列,当且仅当该顶点序列满足下列条件: 若是图中的边(或从顶点i->j有一条路径):则在拓扑序列中顶点i必须排在顶点j之前。在一个有向图中找一个拓扑序列的过程称为拓扑排序[有向图中不允许又回路]

拓扑排序步骤(AOV):

(1)在有向图中选一个没有前驱的顶点且输出

(2)从图中删除该顶点和所有以它为尾的弧

(3)重复上述两步,直到全部的顶点均已输出,或者图中不存在无前驱的顶点为止(代表有向图中有环)

七,关键路径

AOE网: 用一个带顶点权有向图(DAG)描述工程的预计进度。 表示事件,有向边表示活动,边e的权c(e)表示完成活动e所需的 时间(比如天数)。 图中入度为0的顶点表示工程的开始事件(如开工仪式),出度为0的 顶点表示工程结束事件

关键路径:从AOE网中源点到汇点的最长路径,具有最大长度的路径叫 关键路径。

事件v最早开始时间规定源点事件的最早开始时间为0。定义图中任 一事件v的最早开始时间(early event)ee(v)
事件v最迟开始时间定义在不影响整个工程进度的前提下,事件v必 须发生的时间称为v的最迟开始时间(late event) ,记作le(v)。
活动a的最早开始时间e(a)指该活动起点x事件的最早开始时间,
活动a的最迟开始时间l(a)指该活动终点y事件的最迟开始时间与该 活动所需时间之差

计算公式:

事件v最早开始时间ee(v)=MAX{ee(x)+a,ee(y)+b,ee(z)+c}
事件v最迟开始时间le(v)=MIN{le(x)-a,le(y)-b,le(z)-c}
活动a的最早开始时间e(a)=ee(x)
活动a的最迟开始时间l(a)=le(y)-c
关键活动:d(a)=l(a)-e(a),若d(a)为0,则称活动a为关键活动

在AOE网中可能存在多条关键路径
关键活动不按期完成就会影响整个工程的完成时间
所有关键活动都提前完成,整个工程也将提前完成

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

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

相关文章

C语言-数据结构-查找

目录 一,查找的概念 二,线性查找 1,顺序查找 2,折半查找 3,分块查找 三,树表的查找 1,二叉排序树 (1)查找方式: (2)、二叉排序树的插入和生成 (3)、二叉排序树的删除 2,平衡二叉树 (1)、什么是平衡二叉树 (2)、平衡二叉树的插入调整 &#xff08;1&#xff09;L…

【微信小程序】4plus|搜索框-历史搜索 | 我的咖啡店-综合实训

升级版1-清空全部的再次确认 实现功能: 历史搜索记录展示-历史搜索记录展示10条点击跳转-点击历史搜索记录可同步到搜索框并自动搜索全部删除-可一次性全部删除历史搜索记录全部删除-有再次确认操作展示 进行搜索后留下搜索记录 点击垃圾桶图标,显示【清空全部】 点击【清…

macrodroid通过http请求控制手机运行宏

macrodroid adb命令 adb shell pm grant com.arlosoft.macrodroid android.permission.WRITE_SECURE_SETTINGS例:http请求手机播放指定MP3文件 声音素材_电量过低提醒 新建一个宏 添加触发器-连接-http服务器请求 路径随意填,最好不要有特殊符号,不然浏览器识别链接会出错,…

【CSS in Depth 2 精译_098】17.3:CSS 动画延迟技术与填充模式设置 + 17.4:通过 CSS 动画传递意图的秘诀

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第五部分 添加动效 ✔️【第 17 章 动画】 ✔️ 17.1 关键帧17.2 3D 变换下的动画设置 17.2.1 添加动画前页面布局的构建17.2.2 为布局添加动画 17.3 动画延迟与填充模式 ✔️17.4 通过动画传递意图…

慧集通客户案例:致远OA与熵基考勤机集成方案

本原型公司是一家专注大健康产业的综合性高新科技形实体企业&#xff0c;按照单位的战略业务布局&#xff0c;围绕“做强做优、世界一流”的目标&#xff0c;加快内外部资源整合、加强业务协同、优化资源配置&#xff0c;有序推进大健康及相关产业的有机融合&#xff0c;加快构…

深度学习笔记(6)——循环神经网络RNN

循环神经网络 RNN 核心思想:RNN内部有一个“内部状态”,随着序列处理而更新 h t f W ( h t − 1 , x t ) h_tf_W(h_{t-1},x_t) ht​fW​(ht−1​,xt​) h t h_t ht​是new state, h t − 1 h_{t-1} ht−1​是old state, x t x_t xt​是当前时间步的输入,所有时间步共享 f W…

电脑卡顿救星,Mem Reduct 智能清理 10%以上内存

作为一款专业的内存优化工具&#xff0c;Mem Reduct凭借其强大的功能和极致的性能表现&#xff0c;成为众多用户管理系统内存的首选软件。它采用先进的内存管理算法&#xff0c;通过调用系统底层API接口&#xff0c;能够智能识别并清理各类内存占用&#xff0c;包括但不限于系统…

kibana启动报错:Invalid character in header content [“kbn-name“]

启动时候kibana报错&#xff1a; 打开 kibana配置文件&#xff0c;config/kibana.yml&#xff0c;配置上server.name即可&#xff0c;如下&#xff1a;

短视频矩阵系统后端源码搭建实战与技术详解,支持OEM

一、引言 随着短视频行业的蓬勃发展&#xff0c;短视频矩阵系统成为了众多企业和创作者进行多平台内容运营的有力工具。后端作为整个系统的核心支撑&#xff0c;负责处理复杂的业务逻辑、数据存储与交互&#xff0c;其搭建的质量直接影响着系统的性能、稳定性和可扩展性。本文将…

sql group by 多个字段例子

有表如下&#xff1b; 获取某年份、某地区、某产品的销售总额&#xff0c; 或者根据需要把字段顺序换一下&#xff1b; insert into sales (product, year, region, amount) values (飞机,2000,东部,5); insert into sales (product, year, region, amount) values (飞机,2001,…

RBAC权限控制

1、Spring Security 是一个功能强大的Java安全框架&#xff0c;它提供了全面的安全认证和授权的支持。 2 SpringSecurity配置类&#xff08;源码逐行解析&#xff09; Spring Security的配置类是实现安全控制的核心部分 开启Spring Security各种功能&#xff0c;以确保Web应…

ArcGIS Pro地形图四至角图经纬度标注与格网标注

今天来看看ArcGIS Pro 如何在地形图上设置四至角点的经纬度。方里网标注。如下图的地形图左下角经纬度标注。 如下图方里网的标注 如下为本期要介绍的例图&#xff0c;如下&#xff1a; 图片可点击放大 接下来我们来介绍一下 推荐学习&#xff1a;GIS入门模型构建器Arcpy批量…

Kubernetes Gateway API-2-跨命名空间路由

1 跨命名空间路由 Gateway API 具有跨命名空间路由的核心支持。当多个用户或团队共享底层网络基础设施时,这很有用,但必须对控制和配置进行分段,以尽量减少访问和容错域。 Gateway 和 Route(HTTPRoute,TCPRoute,GRPCRoute) 可以部署到不同的命名空间中,路由可以跨命名空间…

Web API和Web Services的区分

前些年一提及自动化测试&#xff0c;大多是指UI界面层的自动化测试。近几年&#xff0c;随着分层自动化测试概念的兴起&#xff0c;以及自动化测试自身的发展与细分&#xff0c;自动化测试包含了更多的内容。 API(Application ProgrammingInterface&#xff0c;应用程序编程接…

使用c#制作坐标

1、建立坐标 2、坐标系的放大缩小 3、标定刻度 4、实时显示鼠标在坐标系上的坐标 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using S…

JVM实战—JVM内存设置与对象分配流转

1.JVM内存划分的原理细节 (1)背景引入 接下来介绍JVM内存的分代模型&#xff1a;新生代、老年代、永久代。现在已知代码里创建的对象&#xff0c;都会进入到Java堆内存中。如下所示&#xff0c;main()方法会周期性执行loadReplicasFromDisk()方法来加载副本数据。 public class…

Debian 12 安装配置 fail2ban 保护 SSH 访问

背景介绍 双十一的时候薅羊毛租了台腾讯云的虚机, 是真便宜, 只是没想到才跑了一个月, 系统里面就收集到了巨多的 SSH 恶意登录失败记录. 只能说, 互联网真的是太不安全了. 之前有用过 fail2ban 在 CentOS 7 上面做过防护, 不过那已经是好久好久之前的故事了, 好多方法已经不…

ASP.NET Core Web API Hangfire

ASP.NET Core Web API Hangfire 前言一、安装二、相关代码1.代码片段2.代码片段3.运行效果 三、测试代码1.即发即弃作业2.延迟作业3.重复作业4.延续作业5.页面调度作业 前言 &#x1f468;‍&#x1f4bb;&#x1f468;‍&#x1f33e;&#x1f4dd;记录学习成果&#xff0c;以…

实用技巧:关于 AD修改原理图库如何同步更新到有原理图 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/144738332 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

【Ubuntu 20.4安装截图软件 flameshot 】

步骤一&#xff1a; 安装命令&#xff1a; sudo apt-get install flameshot 步骤二&#xff1a; 设置快捷方式&#xff1a; Ubuntu20.4 设置菜单&#xff0c;点击 号 步骤三&#xff1a; 输入软件名称&#xff0c; 软件快捷命令&#xff08;flameshot gui&#xff09;&am…