图论算法大合集【包括图的dfs和bfs遍历】【欧拉回路】【判断连通图】【Dijkstra算法】【floyd算法】【最小生成树prim算法】【拓扑排序】

news2025/7/23 8:13:48

图论算法大合集

    • 一. dfs和bfs 过程中要有visited数组标记已遍历过的节点
        • 6-1.1 邻接矩阵存储图的深度优先遍历
        • 6-1.2 邻接表存储图的广度优先遍历
    • 二、欧拉回路(度为偶数,且为连通图)
        • 6-1.3 哥尼斯堡的“七桥问题”
    • 三、判断连通图
        • 6-1.4 地下迷宫探索
    • 四、Dijkstra算法
        • 6-1.5 旅游规划
    • 五、floyd算法
        • 案例6-1.6 哈利·波特的考试
    • 六、最小生存树【prim】(博客)
        • 案例6-1.7 公路村村通 (30 分)
    • 七、BFS和DFS的遍历区别
        • 6-2.1 列出连通集
    • 八、走迷宫或走荷叶,需要dfs(博客)
        • 6-2.3 拯救007
    • 九、拓扑排序(博客)
        • 6-2.6 最短工期

一. dfs和bfs 过程中要有visited数组标记已遍历过的节点

6-1.1 邻接矩阵存储图的深度优先遍历

在这里插入图片描述

void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) )
{
    Visited[V]=true;//先标记顶点被访问
    Visit(V);//访问顶点的邻接点
    for(int i=0;i<Graph->Nv;i++)
    {
        //遍历顶点的邻接点
        if(Graph->G[V][i]==1&&!(Visited[i]))
            DFS(Graph,i,Visit);//如果邻接点可达并且没有被访问过,那么以邻接点为顶点再次进行深度优先遍历
    }
    return;
}

6-1.2 邻接表存储图的广度优先遍历

在这里插入图片描述

void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) )
{
    PtrToAdjVNode p;//边表头指针
    PtrToAdjVNode queue[MaxVertexNum];
    int head=0;
    int tail=0;//定义队列
    Visit(S);
    Visited[S]=true;//标记
    
    queue[tail++]=Graph->G[S].FirstEdge;//将与顶点相连的边表头指针入队
    while(head!=tail)
    {//遍历整个队列
        p=queue[head++];
            while(p!=NULL)
            {
                if(Visited[p->AdjV]==false){//如果没有被访问过
                    queue[tail++]=Graph->G[p->AdjV].FirstEdge;//入队
                    Visit(p->AdjV);
                    Visited[p->AdjV]=true;
                }
                p=p->Next;
            }
    }
}

二、欧拉回路(度为偶数,且为连通图)

6-1.3 哥尼斯堡的“七桥问题”

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
//用全局变量会自动初始化,相当方便喔!
int g[1001][1001];//邻接矩阵储存图
int visited[1001];//访问过了的节点记为1
int du[1001];//记录每个节点的度
int n, m;
 
//最基本的dfs板子
void dfs(int v0) {
	visited[v0] = 1;
	for (int i = 1; i <= n; i++)
		if (visited[i] == 0 && g[v0][i] != 0)
			dfs(i);
}
 
int main() {
	cin >> n >> m;
	int a, b;
	for (int i = 0; i < m; i++) {
		cin >> a >> b;
		g[a][b] = g[b][a] = 1;
		//题目是无向图,相应节点的度加加
		du[a]++;
		du[b]++;
	}
	for (int i = 1; i <= n; i++) {
		//只要有一个节点的度为奇数,就不能存在欧拉回路,直接输出就行!
		if (du[i] % 2 != 0) {
			cout << 0;
			return 0;
		}
	}
	//满足了上面还要保证图连通,dfs和bfs求图连通都可以
	dfs(1);
	//遍历节点,看是否全部标记完
	for (int i = 1; i <= n; i++) {
		if (visited[i] == 0) {
			cout << 0;
			return 0;
		}
	}
	cout << 1;
	return 0;
}

三、判断连通图

6-1.4 地下迷宫探索

在这里插入图片描述

#include<iostream>
#include<string>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int f[1005][1005] , book[1005] , a[1005];
int n , m , s;
int tip = 0;
void dfs(int k)
{
    //a[++tip] = k;
    book[k] = 1;
    for(int i = 1 ; i <= n ; i++ )
    {
        if(f[k][i] == 1 && book[i] == 0)
        {
            cout<<" "<<i;
            dfs(i);
            cout<<" "<<k;
        }
    }
}
int main()
{
    int flag = 1;
    int x , y;
    cin>>n>>m>>s;
    for(int i = 1 ; i <= m ; i++)
    {
        cin>>x>>y;
        f[x][y] = 1;f[y][x] = 1;
    }
    cout<<s;
    dfs(s);
    for(int i = 1 ; i <= n ; i++)
    {
        if(book[i] == 0)
        {
            flag = 0;
            break;
        }
    }
    if(flag == 0)
        cout<<" 0";
}


四、Dijkstra算法

6-1.5 旅游规划

在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>

#define MAXVEX 505
#define INFINITY  65535

void CreateGraph( );
void Dijkstra( int v);


int G[MAXVEX][MAXVEX][2];//定义三维数组
int Num_vertex,Num_edge;
int final[MAXVEX];        //final[]=1表示求得最短路径
int distance[MAXVEX];   //表示求的最短距离
int pay[MAXVEX];       //表示最少费用

int main()
{
    int s,d;
    scanf("%d %d %d %d",&Num_vertex,&Num_edge,&s,&d);
    CreateGraph();
    Dijkstra(s);
    if( distance[d]<INFINITY ){
        printf("%d %d",distance[d],pay[d]);
    }

    return 0;
}

void CreateGraph()
{
    //用邻接矩阵表示图
    int i,j;
    int v1,v2;
    int distance,fee;  //dn表示距离,f表示费用

    for( i=0; i<Num_vertex; i++)
    {
        for( j=0; j<Num_vertex; j++)
        {
            G[i][j][0] = INFINITY;  //初始化
            G[i][j][1] = INFINITY;
        }
    }

    for( i=0; i<Num_edge; i++)  //注意这里是读入边
    {
        scanf("%d %d %d %d",&v1,&v2,&distance,&fee);
        G[v1][v2][0] = G[v2][v1][0]=distance;
        G[v1][v2][1] = G[v2][v1][1]=fee;
    }
}

void Dijkstra( int v)
{
    //求从v结点到其他各结点的最短距离
    int i,j,k;
    int min,cost;
    /*初始化阶段*/
    for( i=0; i<Num_vertex; i++)
    {
        final[i] =0;
        distance[i] =G[v][i][0];   //将与v点有连接的结点加上距离
        pay[i] =G[v][i][1];
    }
    final[v] = 1;
    distance[v] =0;   //V到V距离为0
    pay[v] = 0;

    /*主循环阶段*/
    for( i=1; i<Num_vertex; i++)
    {
        min = INFINITY;     //当前所知离v结点的最近距离
        for( j=0; j<Num_vertex; j++)
        {
            //寻找离v结点的最近距离
            if( !final[j] && distance[j]<min)
            {
                k = j;
                min = distance[j];
                cost = pay[j];
            }
        }

        final[k] = 1;
        for( j=0; j<Num_vertex; j++)
        {
            //修正最短路径和距离
            if( !final[j] && (min+G[k][j][0]<distance[j]))
            {
                distance[j] = min+G[k][j][0];
                pay[j] = cost + G[k][j][1];

            }
            else if( !final[j] && (min+G[k][j][0]==distance[j]) && (cost+G[k][j][1] < pay[j]))
            {

                pay[j] = cost + G[k][j][1];
            }
        }
    }
}

五、floyd算法

案例6-1.6 哈利·波特的考试

在这里插入图片描述

#include<iostream>
#define INT 0x3f3f3f3f
using namespace std;
int main()
{
    int a,b,c[110][110],e,f,g,h,i,j,k,min=INT,max,n;
    for(e=0;e<110;e++)//设初值
        for(f=0;f<110;f++)
        {
            if(e==f)//初值自己变自己就是零喽
                c[e][f]=0;
            else
                c[e][f]=INT;
        }
    cin>>a>>b;
    while(b--)
    {
        cin>>e>>f>>g;
        c[e][f]=c[f][e]=g;
    }
    for(k=1;k<=a;k++)//floyd算法
        for(i=1;i<=a;i++)
            for(j=1;j<=a;j++)
            {
                if(c[i][j]>c[i][k]+c[k][j])
                    c[i][j]=c[i][k]+c[k][j];
            }
    for(i=1;i<=a;i++)//行最高就是选该动物要变所有动物的最小花费
    {
        max=0;
        for(j=1;j<=a;j++)
        {
            if(max<c[i][j])
                max=c[i][j];
        }
        if(min>max)//比较选哪个动物咒语最短
        {
            n=i;
            min=max;
        }
    }
    if(min==INT)//如果min==TNT就说明无论选个动物都存在无法变的动物喽
        cout<<"0"<<endl;
    else
    cout<<n<<' '<<min<<endl;
}

六、最小生存树【prim】(博客)

博客链接
从1开始找到1连接的最短路径点A,然后再从点A找除已经连接的点的最短路径,以此类推。

案例6-1.7 公路村村通 (30 分)

在这里插入图片描述

#include<iostream>
#include<cstring>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1010;
int map[maxn][maxn];
int vis[maxn],dis[maxn];
int n,m;
int prim()
{
	memset(dis,inf,sizeof(dis));
	int sum=0;
	for(int i=0;i<n;++i)
	{
		int t=-1;
		for(int j=1;j<=n;++j)
		{
			if(vis[j]==0&&(t==-1||dis[j]<dis[t]))
				t=j;
		}
		if(i&&dis[t]==inf)
			return inf;
		if(i)
			sum+=dis[t];
		vis[t]=1;
		for(int j=1;j<=n;++j)
			dis[j]=min(dis[j],map[t][j]);
	}
	return sum;	 
}
int main()
{
	int x,y,z;
	cin>>n>>m;
	memset(map,inf,sizeof(map));
	for(int i=1;i<=n;++i)
		map[i][i]=0;
	while(m--)
	{
		cin>>x>>y>>z;
		map[x][y]=map[y][x]=min(map[x][y],z);
	}
	int sum=prim();
	if(sum==inf)
		cout<<-1;
	else
		cout<<sum;
	return 0;
}

七、BFS和DFS的遍历区别

6-2.1 列出连通集

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#define Max 11

int A[Max][Max]={0},B[Max]={0},Q[Max]={0};

int E,N,head = -1,rear = -1;

void DFS(int );

void BFS(int );

void Enqueue(int );

int Dequeue();

int main()
{
	int i,x,y;
	scanf("%d %d",&N,&E);
	for(i=0; i<E; i++){
		scanf("%d %d",&x,&y);
		A[x][y] = 1;
	}
	for(i=0; i<N; i++){
		if(!B[i]){
			printf("{");
			DFS(i);
			printf("}\n");
		}
	}
	for(i=0; i<N; i++)
		B[i] = 0;
	for(i=0; i<N; i++){
		if(!B[i]){
			printf("{");
			BFS(i);
			printf("}\n");
		}
	}
}

void DFS(int v)
{
	int i;
	B[v] = 1;
	printf("%d ",v);
	for(i=v; i<N; i++)
		if(!B[i]&&(A[v][i]||A[i][v]))
			DFS(i);
}

void BFS(int v)
{
	int i;
	B[v] = 1;
	printf("%d ",v);
	Enqueue(v);
	while(head!=rear){
		v = Dequeue();
		for(i=v; i<N; i++)
			if(!B[i]&&(A[v][i]||A[i][v])){
				B[i] = 1;
				printf("%d ",i);
				Enqueue(i);
			}
	}
}

void Enqueue(int i)
{
	Q[++rear] = i;
}

int Dequeue()
{
	return Q[++head];
}

八、走迷宫或走荷叶,需要dfs(博客)

博客链接

6-2.3 拯救007

在这里插入图片描述

#include<iostream>
#include<cmath>
using namespace std;
//1.判断是否能直接从岛上跳到岸上:D+7.5>=50
//2.从岛上跳到一个鳄鱼头上 (第一步): D+7.5>=sqrt(x*x+y*y)
//3.由一个鳄鱼头A跳到另一个鳄鱼头B:(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)<=D*D
//4.判断目前所在的鳄鱼头是否能直接跳到岸上:D>=50-|x|或者D>=50-|y|
//5.每一次跳到鳄鱼头上都要标记为走过了
int N,D,vis[101]={0},a,b;
struct Point{
	int x,y;
}; 
Point point[101];
int jump(int i,int j)	//判断是否能从i跳到j 
{
	int x1=point[i].x;
	int y1=point[i].y;
	int x2=point[j].x;
	int y2=point[j].y; 
	if((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)<=D*D)
		return 1;
	else return 0;	
}
int firstjump(int i)	//判断是否能从岛上直接跳到第i个位置 
{
	int x=point[i].x;
	int y=point[i].y;
	if((D+7.5)*(D+7.5)>=x*x+y*y)
	{
		return 1;
	}else return 0;
}
int canleave(int i)		//判断是否能从这个点跳回岸边 
{
	int x=point[i].x;
	int y=point[i].y;
	if(D>=50-abs(x)||D>=50-abs(y))
	{
		return 1;
	}
	else return 0;
}
int DFS(int i)
{
	int answer=0;
	vis[i]=1;
	if(canleave(i))
	{
		answer=1;
	}else {
		//如果从这个点不能跳回岸边,那我就继续找 
		for(int j=0;j<N;j++)
		{
			if(!vis[j]&&jump(i,j))		//如果没有被访问过 并且可以从这个点跳过去就DFS 
			{
				answer=DFS(j);
				if(answer==1)
				break;
			}
		}
	}
	return answer;
}
int main()
{
	cin>>N>>D;
	for(int i=0;i<N;i++)
	{
		cin>>a>>b;
		point[i].x=a;
		point[i].y=b;
	}
	if(D>=42.5)        //直接从岛上跳到岸上
	{
		cout<<"Yes";
		return 0;
	}
	int answer;
	for(int i=0;i<N;i++)
	{
		if(vis[i]==0&&firstjump(i))
		{
			answer=DFS(i);
			if(answer==1)break;
		}
	}
	if(answer==1)cout<<"Yes";
		else cout<<"No";
}

九、拓扑排序(博客)

6-2.6 最短工期

博客链接
在这里插入图片描述

#include<iostream>
#include<queue>
using namespace std;
int main()
{
    queue<int>l;
    int a,b,c[101][101],d[101]={0},e[101]={0},f,g,h,i,j,ma,ans=0;
// c数组用来存储节点,
/*d数组用来记录完成每个节点的最大时间(只有时间最大,
才能保证该节点的所有节点都完成)并且是最大时间,
不是时间之和*/
//e数组用来记录每个节点的入读数
    for(f=0;f<101;f++)
        for(g=0;g<101;g++)
            c[f][g]=-1;
    cin>>a>>b;
    while(b--)
    {
        cin>>f>>g>>h;
        c[f][g]=h;
        e[g]++;
    }
// 1. 把系列一入队列
    for(f=0;f<a;f++)
        if(e[f]==0)
        {
            ans++;
            l.push(f);
            e[f]=-1;
        }
// 2. 取出队头,遍历连接点,比较两个最大值(走到该节点的最大值,最短时间的最大值)
// 3. 遍历一个节点,入读--如果为0了,入队列
    while(!l.empty())
    {
        f=l.front();
        l.pop();
        for(g=0;g<a;g++)
        {
            if(c[f][g]!=-1&&e[g]>0)
            {
                e[g]--;
                d[g]=max(d[g],d[f]+c[f][g]);
                ma=max(ma,d[g]);
                if(e[g]==0)
                {
                    l.push(g);
                    e[g]=-1;
                    ans++;
                }
            }
        }
    }
//*****最后需要注意的一点,判断是否为有环图
    if(ans!=a)
        cout<<"Impossible"<<endl;
    else
        cout<<ma<<endl;
}

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

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

相关文章

进程调度的基本关系

文章目录1.什么是进程(process)2.进程的特性1.进程是非常重要的"软件资源"2.PCB(进程控制块)描述了哪些进程特征3.并行和并发4.进程的虚拟地址空间和进程间通信1.什么是进程(process) 简单来说就是:一个程序跑起来就是一个进程 一个应用没跑起来叫做程序,跑起来了就…

堆排序算法

一、大顶堆和小顶堆概念 堆排序是利用堆数据结构而设计的一种排序算法&#xff0c;堆排序是一种选择排序&#xff0c;其最坏&#xff0c;最好&#xff0c;平均时间复杂度均为O(nlogn)&#xff0c;同时也是不稳定排序。 堆是具有以下性质的完全二叉树&#xff1a;每个结点的值都…

Hive数据定义语言-DDL-建表高阶语法(内外部、分区、分桶、事务、视图、物化视图)

文章目录1. 内部表、外部表1.1 内部表1.2 外部表1.3 内、外部表差异1.4 Location关键字的作用2. 分区表-Partitioned Tables2.1 概念2.2 创建2.3 分区表数据加载2.3.1 静态分区2.3.2 动态分区2.4 注意事项3. 分桶表-Bucketed Tables3.1 概念3.2 规则3.3 语法3. 事务表-Transact…

编译openMVG出现的错误的解决

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> submodule(s) are missing, please update your repository 在使用CMake生成openMVG解决方案时&#xff0c;出现错误&#xff1a; CMake Error at CMakeL…

另眼看数据中台

目录 前言&#xff1a; 一、故事的开始 二、成也中台&#xff0c;败也中台 1、中台是什么 2、数据中台与企业数字化转型 3、中台的赋能 4、数据中台、业务中台、技术中台 5、中台不一定适合你 ​编辑​编辑小结&#xff1a; 三、 自检数据应用的成熟度 前言&#xff1…

Python学习基础笔记十二——文件

1、目的&#xff1a;是要将数据永久地保存下来&#xff0c;就需要将数据永久保存在硬盘中。 2、概念&#xff1a;文件就是操作系统提供给应用程序来操作硬盘虚拟接口&#xff0c;用户或应用程序通过操作文件&#xff0c;可以将自己的数据永久地保存下来。 3、步骤&#xff1b; …

MACU-Net-用于精细分辨率遥感图像语义分割网络

摘要&#xff1a; 在本文中我们结合了由不同层次的U-Net生成的多尺度特征&#xff0c;设计了一个多尺度跳跃连接和基于非对称卷积的网络--MACU-Net。 网络具有以下几个优点1&#xff09;多尺度跳跃连接将低层和高层特征图中包含的语义特征结合并重新进行排列2&#xff09;非对…

一文搞懂傅里叶级数与变换

描述 这篇文章的目标&#xff1a;以最简单易懂的方式&#xff0c;让大家学会傅里叶变换&#xff01; 为什么要写一篇关于傅里叶变换相关知识的文章呢。有两个原因&#xff1a; 一、这个知识很有趣&#xff0c;可以理解它是一件炫酷的事情。在工作中&#xff0c;一次分享会同事…

BufferPool缓存机制

BufferPool缓存机制 1、更新数据流程 流程图 sql更新数据刷到磁盘前会经过serve层 连接器-管理连接和权限校验优化器-语法词法分析优化器-执行计划生成索引选择执行器-连接bufferPool 1.1 流程步骤 从磁盘加载数据到buffer pool&#xff0c;会先去判断要更新的数据所在数据…

Hantek6022BE 虚拟示波器

​ 0. Hantek 厂家提供的介绍 安装方法按照说明来。 很多人都说原厂的软件不好用&#xff0c;于是折腾就开始了&#xff1a; 1. VIRTINS Multi-Instrument 这个别人已经写的很详细了 大概需要准备 Multi-Ins 这软件&#xff0c;目前找到 3.7 的合用 菜单里 添加设备到库&a…

HTML+CSS详细知识点复习(上)

文章目录一、初识HTML1、标签概述二、初识CSS1、CSS核心基础2、设置文本样式3、高级特性4、CSS的优先级三、CSS选择器1、关系选择器四、盒子模型1、边框属性2、边距属性3、背景属性4、盒子的宽与高5、CSS3新增盒子模型属性一、初识HTML HTML&#xff08;超文本标记语言&#x…

用Python采集世界杯球队热搜数据 并发送邮箱通知

前言 嗨嗨&#xff0c;最近世界杯的热度可是一直在增长啊 待会就是 卡塔尔和塞内加尔打了 怎么说 还是有点期待结果的 趁现在有点无聊 就想着用Python采集世界杯球队热搜数据 顺便 发送邮箱通知 话不多说&#xff0c;马上开始 知识点 动态数据抓包requests发送请求json数据…

【Proteus仿真】【51单片机】智能雨刷器设计

文章目录一、主要功能二、硬件资源三、软件设计四、实验现象联系作者一、主要功能 本项目使用Proteus8仿真51单片机控制器&#xff0c;使用LCD1602液晶模块、按键模块、雨滴传感器、ADC、LED模块等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示雨刷器当前模式、…

如何制定测试团队度量体系

1、前言 每当月底或一个季度结束&#xff0c;公司或项目都会进行考核指标的统计&#xff0c;来总结每个组员在这个阶段的工作产出与绩效成绩。 那么制定哪些指标最为标准&#xff0c;最为专业&#xff0c;同时针对整个项目组都是公平的&#xff0c;这个就需要每个公司或项目根…

Python入门

目录 一、Python安装及环境搭建 二、Python运用&#xff08;数据类型&#xff09; 基本数据类型 引用数据类型 一、Python安装及环境搭建 Python环境安装包下载 https://www.python.org/ https://www.python.org/downloads/windows/ Python开发工具PyCharm下载 https://www.…

南卡和FIIL 哪个更好用?南卡和FIIL CC nano蓝牙耳机对比测评

作为一个狂热的蓝牙爱好者&#xff0c;我也用了不少蓝牙耳机了&#xff0c;真的是对蓝牙耳机爱不释手。自从蓝牙耳机出现以来&#xff0c;我们都看到了它的迅速发展&#xff0c;尤其是这两年&#xff0c;蓝牙耳机越来越受欢迎&#xff0c;已经取代了传统的有线耳机&#xff0c;…

1-10嵌入式Linux系统开发与应用|嵌入式Linux|第三章 Linux编程环境

目录 1.掌握Linux常用的基本命令功能、语法结构和用法示例 1.1linux编程环境 1.1.1系统平台环境 linux平台特性 1.1.2开发工具环境 1.1.3基于文模式的开发平台 1.1.4集成开发平台EclipseCDT 1.1.5文档帮助环境 1.2常用编辑器 1.2.1VIM编辑器 1.VIM的模式 2.VIM的启…

爆冷?黑马?这次用python来给你推测一波.....

人生苦短 我用python 在刚刚结束的2022年卡塔尔世界杯E组第一轮一场比赛中&#xff0c; 德国队爆冷1:2不敌日本队。 上半场&#xff0c;日本队门将权田修一出击扑倒劳姆送点&#xff0c; 京多安主罚命中先拔头筹&#xff1b; 下半场&#xff0c;堂安律门前补射为日本队扳平…

如何裁剪视频画面?快来看看这个详细教程

有什么简单的方法可以裁剪视频&#xff1f;现在有很多小伙伴都会在社交平台上发布自己的视频内容&#xff0c;分享自己的日常&#xff0c;那在编辑视频的时候肯定是会对视频内容进行剪切的&#xff0c;那么怎么裁剪视频呢&#xff1f;有哪些简单的方法可以裁剪视频呢&#xff1…

Selenium基础 — TMLTestRunner测试报告

目录 1、HTMLTestRunner介绍 2、HTMLTestRunner的使用 3、测试报告示例 4、封装成模块 1、学习思路和方法 2、想学习却无从下手&#xff0c;该如何学习&#xff1f; 3、软件测试/自动化测试【全家桶装】学习中的工具、安装包、插件.... 4、有了安装包和学习资料&#x…