最短路算法——差分约束
差分约束
(1) 求不等式组的可行解
- 源点:从源点出发,一定可以走到所有的边
- 求可行解步骤:
- 先将每个不等式 x i ≤ x j + c x_i \le x_j + c xi≤xj+c,转化成一条从 s j s_j sj走到 s i s_i si,长度为 c k c_k ck 的一条边
- 找一个超级源点,使得该源点一定可以遍历到所有边
- 从源点求一遍单源最短路
- 结果一:如果存在负环,则原不等式组一定无解
- 结果二:如果没有负环,则 d i s t [ i ] dist[i] dist[i]就是原不等式组的一个可行解
(2) 如何求最大值或最小值
- 结论: 如果求的是最小值,则应该求最长路;如果求的是最大值,则应该求最短路;
- 问题1:如何转化 x i ≤ c x_i \le c xi≤c,其中c是一个常数
- 方法:建立一个超级源点,0,然后建立0->i,长度是c的边即可。
- 以求 x i x_i xi的最大值为例:求所有从 x i x_i xi出发,构成的不等式链 x i ≤ x j + c j ≤ x k + c 2 + c 1 ≤ . . . ≤ c 1 + c 2 + . . . x_i \le x_j+c_j \le x_k + c_2 + c_1 \le ...\le c_1+c_2+... xi≤xj+cj≤xk+c2+c1≤...≤c1+c2+...所计算出的上界(而这个上界要让所有关系都成立,那么就必须以最小的上界为上界,因此需要用最短路算法求到i这个点的最短距离)
(3) 关系:
每一个差分约束的问题都可以转换成最短路的问题
理论理解
题单
1. 糖果
第一眼:
- 感觉和floyd的排序那一道题有点相似之处,两个点之间都有关系(ps:关系闭包)
- 和排序不一样的地方在于,这道题确定小朋友各种胡搅蛮缠的糖多糖少要求后,老师需要准备的糖个数的最小值
思考:
- 怎么去结合这两种题目要求呢,一开始能想到的处理就是先处理关系闭包问题,同时用一个ans去记录老师需要准备的糖的数量从最少的1个开始,关系环到一个一个往后的大于关系也只是加1(这个时候又想到记录方案数那题),如果是相等的关系,当前节点的方案数是前一点的一倍,如果大于关系,当前节点的方案数等于前个节点加一,最后老师需要准备糖果的个数就是总的方案数,该觉还是可以spfa走一波,开一个cnt数组那样子
- 这样要怎么考虑所有关系呢
听y说:
- 二刷视频
- 我悟了。就是这题它并没有直接给出我需要给某个小朋友多少糖,只给出了每个小朋友糖的相对数量关系,而我们需要一个超级源点,去遍历到所有的边。
- 关于求最小值用最长路建边并做spfa求最长路,
#include<bits/stdc++.h>using namespace std;
#define int long long
int n,k;
const int N=1e5+10,M=3*N;
int h[N],e[M],ne[M],w[M],idx;
int d[N],q[N],st[N],cnt[N];void add(int a,int b,int c){e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}bool spfa(){memset(d,-0x3f,sizeof d);d[0]=0;int hh=0,tt=1;q[hh]=0;while(hh!=tt){int t=q[--tt];if(tt==N) tt=0;st[t]=0;for(int i=h[t];i!=-1;i=ne[i]){int j=e[i];if(d[j]<d[t]+w[i]){d[j]=d[t]+w[i];cnt[j]=cnt[t]+1;if(cnt[j]>=n+1) return 0;if(!st[j]){st[j]=1;q[tt++]=j;if(tt==N)tt=0;}}}}return 1;
}signed main(){scanf("%lld%lld",&n,&k);memset(h,-1,sizeof h);for(int i=0;i<k;i++){int x,a,b;scanf("%lld%lld%lld",&x,&a,&b);if(x==1) add(b,a,0),add(a,b,0);else if(x==2) add(a,b,1);else if(x==3) add(b,a,0);else if(x==4) add(b,a,1);else if(x==5) add(a,b,0);}for(int i=1;i<=n;i++) add(0,i,1);int res=spfa();if(!res){puts("-1");}else{res=0;for(int i=1;i<=n;i++) res+=d[i];printf("%lld",res);}return 0;
}
用先进先出的栈
2. 区间
第一眼:
- 如果要让Z包含的数尽可能少,那就让一个区间的数集中在和其他区间相交的部分就可以贪心的解决这个问题了吧
听y说:
- 用差分约束的思想做很牛逼,同时利用前缀和的思想,绝绝子
- 两个端点约束关系:
- s [ i ] ≥ s [ i − 1 ] s[i] \ge s[i-1] s[i]≥s[i−1]
- $s[i]-s[i-1] \le 1 $
- [ a , b ] [a,b] [a,b] s [ b ] − s [ a − 1 ] ≥ c s[b]-s[a-1] \ge c s[b]−s[a−1]≥c
- 转换成最短路模型——求最长路
- s [ i ] ≥ s [ i − 1 ] s[i] \ge s[i-1] s[i]≥s[i−1]
- s [ i − 1 ] ≥ s [ i ] − 1 s[i-1] \ge s[i] -1 s[i−1]≥s[i]−1
- s [ b ] ≥ s [ a − 1 ] + c s[b] \ge s[a-1]+c s[b]≥s[a−1]+c
- 接着就是模版框框的打了
#include<bits/stdc++.h>using namespace std;
//关于这里的N和M的取值,因为M代表边数,我们以最大值N建边
//最多会建3*N条边,如果也算上第N个点的位置的话,会数组越界,可以开大一个数量级
//因为并没有特别熟练空间复杂度以及并不料想到后他数据怎么卡,就开大一个数量级过了
const int N=5e4+10,M=4*N+10;
int m;
int h[N],e[M],w[M],ne[M],idx;
int d[N],st[N],cnt[N],q[N];void add(int a,int b,int c){e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}bool spfa(){memset(d,-0x3f,sizeof d);d[0]=0;int hh=0,tt=1;while(hh!=tt){int t=q[hh++];if(hh==N) hh=0;st[t]=0;for(int i=h[t];i!=-1;i=ne[i]){int j=e[i];if(d[j]<d[t]+w[i]){d[j]=d[t]+w[i];if(!st[j]){st[j]=1;q[tt++]=j;if(tt==N) tt=0;}}}}}signed main(){scanf("%d",&m);memset(h,-1,sizeof h);for(int i=1;i<N;i++){add(i-1,i,0);add(i,i-1,-1);}while(m--){int a,b,c;scanf("%d%d%d",&a,&b,&c);a++,b++;add(a-1,b,c);}spfa();printf("%d",d[50001]);return 0;
}
3. 排队布局
第一眼:
- 又是usaco的牛,好多事的牛
- 1和n之间可以任意大,说明1或n都没有能够约束他们的其他牛
- 不存在满足要求,是不是两头牛之间的约束关系会存在矛盾
思考:
学差分约束的时候时把这道题和糖果(第一题)进行着对比来学的
- 糖果——求最小值——求最长路
- 本题——求最大值
索性先自己思考并落实一遍
- 两头牛之间距离差分约束关系
- 原本编号的先后顺序: s [ i ] < = s [ i + 1 ] s[i]<=s[i+1] s[i]<=s[i+1]
- 前 M L M_L ML条边: s [ a ] − s [ b ] ≤ c s[a]-s[b] \le c s[a]−s[b]≤c
- 后 M D M_D MD条边: s [ a ] − s [ b ] ≥ c s[a]-s[b] \ge c s[a]−s[b]≥c
- 最短路;
- s [ i ] < = s [ i + 1 ] s[i]<=s[i+1] s[i]<=s[i+1]
- s [ a ] ≤ s [ b ] + c s[a] \le s[b]+c s[a]≤s[b]+c
- s [ b ] ≤ s [ a ] − c s[b] \le s[a]-c s[b]≤s[a]−c
- Tips:
为什么n一定能到其他所有边?
- 因为第一条约束关系
隐含的前缀和思想
#include<bits/stdc++.h>using namespace std;
//需要思考怎么建边,约束条件如何化成边
const int N=1e3+10,M=2e4+10+2*N,INF=0x3f3f3f3f;
int n,l,d;
int h[N],e[M],w[M],ne[M],idx;
int dist[N],st[N],cnt[N],q[N];void add(int a,int b,int c){e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}int spfa(int s){memset(dist,0x3f,sizeof dist);memset(st,0,sizeof st);memset(cnt,0,sizeof cnt);dist[s]=0;int hh=0,tt=1;q[hh]=s;while(hh!=tt){int t=q[hh++];if(hh==N) hh=0;st[t]=0;for(int i=h[t];i!=-1;i=ne[i]){int j=e[i]; if(dist[j]>dist[t]+w[i]){dist[j]=dist[t]+w[i];cnt[j]=cnt[t]+1;if(cnt[j]>=n+1) return -1;if(!st[j]){st[j]=1;q[tt++]=j;if(tt==N) tt=0;}}}}return 1;
}signed main(){cin>>n>>l>>d;memset(h,-1,sizeof h);for(int i=1;i<n;i++){add(i+1,i,0);add(0,i,0);}add(0,n,0);for(int i=0;i<l;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);if(a>b) swap(a,b);add(a,b,c);}for(int i=0;i<d;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);if(a>b) swap(a,b);add(b,a,-c);}int res=spfa(0);if(res==-1) puts("-1");else{spfa(1);printf("%d",dist[n]==INF?-2:dist[n]);}return 0;
}
4. 雇佣收银员
第一眼:
- 感觉和区间会很像,一个时间段如果需要很多营业员,那么就让每个营业员的工作时间尽可能覆盖到这个区间
- 输入处理比较麻烦(第二眼,实际上还好,就是变量表示需要思考一下
思考:
建边操作:
用区间表示所需,采用前缀和来建立关系:
某一时刻的营收员人数要大于等于这一时刻所需要的营收员人数
上岗人数不能超过申请人数
以时刻作为点
i时刻所需,i时刻申请,像是隐含的关系,就是一个人工作时长导致的区间内申请人数的变化仍然需要满足能够在某时刻大于等于所需的人数
然后是某一时刻的申请人数也可以用前缀和来表示,于是可以x[i]的建边也可以用 s u m [ i ] − s u m [ i − 1 ] sum[i]-sum[i-1] sum[i]−sum[i−1]来表示
s u m [ i ] sum[i] sum[i] x [ i ] x[i] x[i] r [ i ] r[i] r[i] n u m [ i ] num[i] num[i]
上岗人数约束关系如下:
- 某一时刻的上岗人数 : s u m [ i ] − s u m [ i − 1 ] > = 0 sum[i]-sum[i-1]>=0 sum[i]−sum[i−1]>=0
- 某一时刻的上岗和申请人数之间的关系: s u m [ i ] − s u m [ i − 1 ] ≤ n u m [ i ] sum[i]-sum[i-1]\le num[i] sum[i]−sum[i−1]≤num[i]
- 某一时刻的所在的上岗人数,
- [ 1 , 7 ] [1,7] [1,7]: s u m [ i ] + s u m [ 24 ] − s u m [ 24 − ( 7 − i ) ] > = r [ i ] sum[i]+sum[24]-sum[24-(7-i)]>=r[i] sum[i]+sum[24]−sum[24−(7−i)]>=r[i]即 s u m [ i ] + s u m [ 24 ] − s u m [ 16 + i ] > = r [ i ] sum[i]+sum[24]-sum[16+i]>=r[i] sum[i]+sum[24]−sum[16+i]>=r[i]
- [ 8 , 24 ] [8,24] [8,24]: s u m [ i ] − s u m [ i − 8 ] > = r [ i ] sum[i]-sum[i-8]>=r[i] sum[i]−sum[i−8]>=r[i]
转换成最短路模型如下:
- s u m [ i ] > = s [ i − 1 ] sum[i]>=s[i-1] sum[i]>=s[i−1]
- s u m [ i − 1 ] > = s u m [ i ] − n u m [ i ] sum[i-1]>=sum[i]-num[i] sum[i−1]>=sum[i]−num[i]
- s u m [ i ] > = s u m [ 16 + i ] − s u m [ 24 ] + r [ i ] sum[i]>=sum[16+i]-sum[24]+r[i] sum[i]>=sum[16+i]−sum[24]+r[i]
- s u m [ i ] > = r [ i ] + s u m [ i − 8 ] sum[i]>=r[i]+sum[i-8] sum[i]>=r[i]+sum[i−8]
#include<bits/stdc++.h>using namespace std;
const int N=30,M=100;
int n,sum[N],r[N],num[N];
int h[N],e[M],ne[M],w[M],idx;
int cnt[N],st[N],q[M],d[N];void add(int a,int b,int c){e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}void build(int c){memset(h,-1,sizeof h);idx=0;for(int i=1;i<=24;i++){add(i-1,i,0);add(i,i-1,-num[i]);}for(int i=1;i<=7;i++) add(16+i,i,r[i]-c);for(int i=8;i<=24;i++) add(i-8,i,r[i]);add(0,24,c),add(24,0,-c);
}bool spfa(int s24){memset(d,-0x3f,sizeof d);memset(st,0,sizeof st);memset(cnt,0,sizeof cnt);build(s24);int hh=0,tt=1;d[0]=0;q[0]=0;while(hh!=tt){int t=q[hh++];if(hh==N) hh=0;st[t]=0;for(int i=h[t];i!=-1;i=ne[i]){int j=e[i];if(d[j]<d[t]+w[i]){d[j]=d[t]+w[i];cnt[j]=cnt[t]+1;if(cnt[j]>=25) return false;if(!st[j]){st[j]=1;q[tt++]=j;if(tt==N) tt=0;}}}}return true;
}signed main(){int t;cin>>t;while(t--){memset(num,0,sizeof num);for(int i=1;i<=24;i++){scanf("%d",r+i);}cin>>n;while(n--){int x;scanf("%d",&x);num[x+1]++;}int res=0;for(int i=0;i<=1000;i++){//res=spfa(i);if(spfa(i)){res=1;cout<<i<<endl;break;}}if(!res)puts("No Solution");}return 0;
}
2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
4
0
8
16
16
相关文章:

最短路算法——差分约束
差分约束 (1) 求不等式组的可行解 源点:从源点出发,一定可以走到所有的边求可行解步骤: 先将每个不等式 x i ≤ x j c x_i \le x_j c xi≤xjc,转化成一条从 s j s_j sj走到 s i s_i si,长度为 c k c_k ck 的一条边找…...

Log4j日志框架讲解(全面,详细)
目录 Log4j概述 log4j的架构(组成) Loggers Appenders Layouts 快速入门 依赖 java代码 日志的级别 log4j.properties 自定义Logger 总结: Log4j概述 Log4j是Apache下的一款开源的日志框架,通过在项目中使用 Log4J&…...
LeetCode 35, 242, 994
目录 35. 搜索插入位置题目链接标签思路代码 242. 有效的字母异位词题目链接标签思路代码 994. 腐烂的橘子题目链接标签思路代码 35. 搜索插入位置 题目链接 35. 搜索插入位置 标签 数组 二分查找 思路 本题与 704. 二分查找 十分相似,只不过本题在找不到 tar…...

ctfshow-web入门-文件包含(web87)巧用 php://filter 流绕过死亡函数的三种方法
目录 方法1:php://filter 流的 base64-decode 方法 方法2:通过 rot13 编码实现绕过 方法3:通过 strip_tags 函数去除 XML 标签 除了替换,新增 file_put_contents 函数,将会往 $file 里写入 <?php die(大佬别秀了…...
adb shell ps -T打印出来参数的含义,以及D,T,Z代表的状态含义是什么?
在Android系统中,使用adb shell ps命令可以查看当前系统中运行的进程信息。当你添加-T选项时(注意,标准的ps命令在Android的adb shell中可能不直接支持-T选项,这通常与Linux中的ps命令略有不同),你可能是想…...
leetcode77组合——经典回溯算法
本文主要讲解组合的要点与细节,以及回溯算法的解题步骤,按照步骤思考更方便理解 c和java代码如下,末尾 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 具体要点: …...

springcloud-alibba之FeignClient
代码地址:springcloud系列: springcloud 组件分析拆解 1.FeignClient的集成 springboot版本:3.1.5 springcloud组件版本:2022.0.4 nacos客户端的版本:2.3.2 1.引pom 这里引入了nacos和feginclient的版本 <dependency>…...

三、docker配置阿里云镜像仓库并配置docker代理
一、配置阿里云镜像仓库 1. 登录阿里云官网,并登录 https://www.aliyun.com/ 2. 点击产品 - 容器 - 容器与镜像服务ACR - 管理控制台 - 镜像工具 - 镜像加速器 二、配置docker代理 #1. 创建docker相关的systemd文件 mkdir -p /etc/systemd/system/docker.servic…...

【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(十一)-git(3)
Git是目前最流行的版本控制系统之一,在现代软件开发中扮演着重要的角色。它能够有效地跟踪文件变化、协作开发,并存储项目的历史记录。本文的目的是向读者介绍Git的基本概念和工作原理,帮助初学者快速上手使用Git,并帮助有经验的开…...

全面解析 TypeScript 泛型的二三事
2024年了相信大家都已经在日常开发的过程中使用上了 TypeScript 了。TypeScript 增强了代码可靠性和可维护性,确保减少运行时错误并提高开发人员的工作效率。 TypeScript 通过类型声明 使得 javascript 拥有了强类型校验。而泛型的是类型声明中最重要的一环&#x…...

单/多线程--协程--异步爬虫
免责声明:本文仅做技术交流与学习... 目录 了解进程和线程 单个线程(主线程)在执行 多线程 线程池 协程(爬虫多用) 假异步:(同步) 真异步: 爬虫代码模版 异步-爬虫 同步效果--19秒 异步效果--7秒 了解进程和线程 # --------------------> # ------> # …...
android pdf框架-11,查看图片
前10篇文章,9章关于pdf的,pdf解析后,里面也是有各种图片,于是利用pdf的view来展示图片,似乎也是个不错的想法. android手机中的图片查看功能,有的可以展示,有的不能.比如华为,荣耀对大体积的png是可以显示的,小米是不显示,只有缩略图. 一张png50m大,比如清明上河图,原图是tif…...
【CSS】深入浅出弹性布局
CSS的弹性布局(Flexbox)是一种用于在容器中沿着一维方向(水平或垂直)来布局、对齐和分配容器内项目空间的有效方式。它旨在提供一个更加有效的方式来布局、对齐和分配容器中项目的空间,即使它们的大小未知或是动态变化…...

医院挂号系统小程序的设计
管理员账户功能包括:系统首页,个人中心,患者管理,医生管理,专家信息管理,科室管理,预约信息管理,系统管理 微信端账号功能包括:系统首页,专家信息࿰…...

广州外贸建站模板
Yamal外贸独立站wordpress主题 绿色的亚马尔Yamal外贸独立站wordpress模板,适用于外贸公司建独立站的wordpress主题。 https://www.jianzhanpress.com/?p7066 赛斯科Sesko-W外贸建站WP主题 适合机械设备生产厂家出海做外贸官网的wordpress主题,红橙色…...

KDP数据分析实战:从0到1完成数据实时采集处理到可视化
智领云自主研发的开源轻量级Kubernetes数据平台,即Kubernetes Data Platform (简称KDP),能够为用户提供在Kubernetes上的一站式云原生数据集成与开发平台。在最新的v1.1.0版本中,用户可借助 KDP 平台上开箱即用的 Airflow、AirByte、Flink、K…...

【人工智能】-- 智能机器人
个人主页:欢迎来到 Papicatch的博客 课设专栏 :学生成绩管理系统 专业知识专栏: 专业知识 文章目录 🍉引言 🍉机器人介绍 🍈机器人硬件 🍍机械结构 🍍传感器 🍍控…...

Android广播机制
简介 某个网络的IP范围是192.168.0.XXX,子网 掩码是255.255.255.0,那么这个网络的广播地址就是192.168.0.255。广播数据包会被发送到同一 网络上的所有端口,这样在该网络中的每台主机都将会收到这条广播。为了便于进行系统级别的消息通知&…...
SQL FOREIGN KEY
SQL FOREIGN KEY 简介 SQL(Structured Query Language)是用于管理关系数据库管理系统(RDBMS)的标准编程语言。在SQL中,FOREIGN KEY是一个重要的概念,用于建立和维护数据库中不同表之间的关系。本文将详细介绍SQL FOREIGN KEY的概念、用途、以及如何在SQL中实现和使用FO…...

绘唐3最新版本哪里下载
绘唐3最新版本哪里下载 绘唐最新版本下载地址 推文视频创作设计是一种通过视频和文字的形式来进行推广的方式,可以通过一些专业的工具来进行制作。 以下是一些常用的小说推文视频创作设计工具: 视频剪辑软件:如Adobe Premiere Pro、Fina…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...