树和图论(详细整理,简单易懂!)
树和图论
树的遍历模版
#include <iostream>
#include <cstring>
#include <vector>
#include <queue> // 添加queue头文件
using namespace std;const int MAXN = 100; // 假设一个足够大的数组大小
int ls[MAXN], rs[MAXN]; // 定义左右子树数组//后序遍历
void dfs(int x) {if(ls[x]) dfs(ls[x]);if(rs[x]) dfs(rs[x]);cout << x << ' ';
}//层序遍历
void bfs() {queue<int> q;//起始节点入队q.push(1);//队列不为空则循环while(q.size()) {//访问队列元素xint x = q.front();//取出队列元素q.pop();//一系列操作cout << x << " ";if(ls[x]) q.push(ls[x]);if(rs[x]) q.push(rs[x]);}
}
int main() {int n;cin >> n;for(int i = 1; i <= n; i++) {cin >> ls[i] >> rs[i];}dfs(1);cout << endl;bfs();return 0;
}
最近公共祖先LCA
本质是一个dp,类似于之前的ST表
fa[i][j]
表示i
号节点,向上走2^j所到的节点,当dep[i]-2^j>=1
时fa[i][j]
有效
又因为我们知道2^(j-1) + 2^(j-1)= 2^j, i的2^(j-1) 级祖先的2^(j-1)级祖先 就是i的2^j级祖先。
形象理解:
我们要求x(5号节点)与y(10号节点)的 LCA
倍增的时候,我们发现y的深度比x的深度要小,于是现将y跳到8号节点,使他们深度一样:
这个时候,x和y的深度就相同了,于是我们按倍增的方法一起去找LCA
我们知道n(10)之内最大的二的次方是8,于是我们向上跳8个单位,发现跳过了。
于是我们将8/2变成4,还是跳过了。
再将4/2变成2,跳到了0号节点。
虽然这时跳到了LCA,但是如果直接if(x==y)就确定的话,程序无法判断是刚好跳到了还是跳过了,应为跳过了x也等于y
于是我们需要刚好跳到LCA的儿子上,然后判断if(x的爸爸==y的爸爸)来确定LCA
由于每一个数都可以分解为几个2^n的和(不信自己试),所以他们一定会跳到LCA的儿子上
于是我们就找到了LCA啦!
代码模版:
int lca(int x,int y){//x喜欢跳。。。//如果x深度比y小,交换x和y 保证x深度大if(dep[x]<dep[y]) swap(x,y); //贪心:i从大到小 //x向上跳的过程中,保持dep[x]>=dep[y],深度不能超过y for(int i=20;i>=0;i--){if(dep[fa[x][i]]>=dep[y]) x=fa[x][i];} //x跳完 此刻x和y的dep相同//如果发现相遇了 那么就是这个点if(x==y) return x;//(int)(log(n)/log(2))就是n以内最大的2的次方,从最大的开始倍增for(int i=(int)(log(n)/log(2));i>=0;i--) //如果x和y爸爸不想同 则没有找到//整个跳跃过程中,保持x!=y,不用x=y判断if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];//x和y一起向上跳 return fa[x][0];//返回他们的爸爸,即是LCA
}
可是在写LCA之前,我们还得进行预要处理些什么呢?
1.每一个点的深度,以便到时候判断
2.每一个点2^i级的祖先,以便到时候倍增跳
于是我们用一个dep数组来记录每一个点的深度,再用一个fa[i][j]
表示节点i的2^j级祖先
void dfs(int x,int p){dep[x]=dep[p]+1;//x的深度是他父亲的深度+1 fa[x][0]=p;//2^0是1,x向上一个的祖先就是他爸爸for(int i=1;i<=20;i++) fa[x][i]=fa[fa[x][i-1]][i-1];//父节点再向上2^i-1 for(const auto &y : g[x]){ //枚举x所有儿子if(y==p) continue;//如果不是他爸爸 继续dfsdfs(y,x);}
}
树的重心
指对于某个点,将其删除后,可以是的剩余联通块的最大值最小的点(剩余的若干子树的大小最小)
性质:
- 中心若干棵子树大小一定**<=n/2**;除了重心以外的所有其他节点,都必然存在一棵节点个数>n/2的子树
- 一棵树至多两个重心,如果存在,则必然相邻;将连接两个重心的边删除后,一定划分为两棵大小相等的树
- 树中所有点到某个点的距离和中,到重心的距离和是最小的
- 两棵树通过一条边相连,重心一定在较大的一棵树一侧的连接点与原重心之间的简单路径上。两棵树大小相同,则重心就是两个连接点。
如何求解重心?
跑一遍dfs,如果mss[x]<=n/2,则x是重心,反之不是。
void dfs(int x,int fa){//初始化mss/sz数组sz[x]=1,mss[x]=0;for(const auto& y:g[x]){if(y==fa) continue;dfs(y,x);sz[x]+=sz[y];mss[x]=max(mss[x],sz[y]);}//后序位置比较mss大小并判断mss[x]=max(mss[x],n-sz[x]);if(mss[x]<=n/2) v.push_back(x);
}
树的直径
树上任意两节点之间最长的简单路径即为树的「直径」。
直径由u,v决定,若有一条直径(u,v)满足 : **1)**u和v度数均为1;2)在任意一个点为根的树上,u和v中必然存在一个点作为最深的叶子节点。
如何求解直径?
跑两遍dfs:以任意节点为根的树上跑一次dfs求所有点的深度,选最大的点作为u,再以u为根拍一次dfs,最深的点为v,路径上点的个数为树的dep[v]+1
(根节点深度为0)/ dep[v]
(根节点深度为1)
树上差分
差分的思想方法:
如果有一个区间内的权值发生相同的改变的时候,我们可以采用差分的思想方法,而差分的思想方法在于不直接改变区间内的值,而是改变区间[ L , r ] 对于 区间 [ 0, L - 1 ] & 区间[ r + 1, R]的 相对大小关系
差分,可以当做前缀和的逆运算。既然是逆运算,运算方法自然就是相反的了。定义差分数组
d i f f i = a i − a i − 1 diff_i=a_i-a_{i-1} diffi=ai−ai−1
compare:
原数列 | 9 | 4 | 7 | 5 | 9 |
---|---|---|---|---|---|
前缀和 | 9 | 13 | 20 | 25 | 34 |
差分数组 | 9 | -5 | 3 | -2 | 4 |
前缀和的差分数组 | 9 | 4 | 7 | 5 | 9 |
查分数组的前缀和 | 9 | 4 | 7 | 5 | 9 |
树上差分,就是利用差分的性质,对路径上的重要节点进行修改(而不是暴力全改),作为其差分数组的值,最后在求值时,利用dfs遍历求出差分数组的前缀和,就可以达到降低复杂度的目的。
这里差分的优点就非常明显了:
- 算法复杂度超低
- 适用于一切 连续的 “线段”
这里所谓的线段可以是一段连续的区间,也可以是路径
点差分:
模版题目:给出一棵 n 个点的树,每个点点权初始为 0,现在有 m 次修改,每次修改给出 x,y,将 x,y 简单路径上的所有点的点权 +d,问修改完之后每个点的点权。
将序列差分转移到树上:比如我们要对 x,y 的路径上的点统一加上 d。
涉及到的点有:x,h,b,f,y
因此对于点 a
我们不能有影响,操作方案就是 b(回溯时左右加了两次)的点权减去 d,a 的点权减去 d。
最后我们对整棵树做一遍 dfs,将所有点的点权变为其子树(含自己)内所有点的点权,这个操作仿照求每个点子树的 Size 就可以完成了。
模版代码:
同样需要lca的两个模版函数,并添加:
dlt[i]
:存放每个点经过的次数
void dfs1(int x){for(int i=0;i<v[x].size();i++){int u=v[x][i];if(u!=fa[x][0]){dfs1(u);//回溯dlt[x]+=dlt[u];}}return;
}
int main() {cin>>n>>k;maxx=log2(n); for(int i=1;i<n;i++){int a,b;cin>>a>>b;v[a].push_back(b),v[b].push_back(a); }dfs(1,0);//k次询问 处理k条路径 for(int i=1;i<=k;i++){int a,b;cin>>a>>b;dlt[a]++,dlt[b]++;int c=lca(a,b);dlt[c]--,dlt[fa[c][0]]--;}dfs1(1);for(int i=1;i<=n;i++) cout<<dlt[i]<<" ";return 0;
}
美妙的例题:
[P3258 JLOI2014] 松鼠的新家 - 洛谷 (luogu.com.cn)
边差分:
模版题目:给出一棵 n个点的树,每条边边权初始为 0,现在有 m 次修改,每次修改给出 x,y将 x,y简单路径上的所有边边权 +d,问修改完之后每条边的边权。
首先我们需要一种叫做**“边权转点权”的方法,就是对于每个点我们认为其点权代表这个点与其父节点之间的边的边权**,对于每条边我们认为其边权是这条边所连两个点中深度较大的点的点权,根节点点权无意义。
还是修改 x,y路径上的边,还是这张图:

涉及的边/点:x,h,f,y
,对于点 b
我们不能有影响,操作方案就是 b(回溯时左右加了两次 实则不变)的点权(b与父亲节点的边权)减去 2d。
同样的做完之后一遍 dfs 求一下每个点的点权即可。
图的遍历模版
DFS:
bitset<N> vis;//vis[i]=true说明i点已经走过
void dfs(int x){vis[x]=true;for(const auto& y:g[x]){if(vis[y]) continue;dfs(y);}
}
BFS:
维护一个queue,通常用于求边权相等情况下的最短距离
bitset<N> vis;
queue<int> qu;
void bfs() { qu.push(1);//从1开始while (!qu.empty()) { int x = qu.front(); qu.pop(); if (vis[x]) continue; // 避免重复处理 vis[x] = true; // 标记已访问 for (const auto& y : g[x]) { if (!vis[y]) qu.push(y); // 未访问的邻居入队 } }
}
例题1:帮派弟位
找到每个节点i
的子树大小siz[i]
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+9;
vector<int> g[N];
int siz[N];//存放包含自己在内的子树节点个数
void dfs(int x,int p){siz[x]=1;//叶子如果设为0则对父节点的size毫无影响for(const auto &y:g[x]){if(y==p) continue;dfs(y,x);siz[x]+=siz[y];}
}
struct Node{int id,siz;//rule:主要按 siz 降序(siz > u.siz) siz 相同,则按 id 升序(id < u.id)bool operator < (const Node &u)const {return siz==u.siz?id<u.id:siz>u.siz;}
};int main()
{int n,m;cin>>n>>m;for(int i=1;i<n;i++){int r,l;cin>>l>>r;//存储有向树g[r].push_back(l);}dfs(1,0);//v存储每个编号的手下人数多少vector<Node> v;//vector下标必须从0开始i=0存for(int i=0;i<n;i++) v.push_back({i,siz[i]-1});sort(v.begin(),v.end());for(int i=0;i<n;i++) if(v[i].id==m) cout<<i+1<<endl;return 0;
}
例题2: 可行路径的方案数
计算从节点 1
到节点 n
的最短路径数量
理解:
- “当前路径” = 从城市1到
x
的已知最短路径 + 边x→y
。 - 这条路径的长度是
d[x] + 1
(因为所有边权为1,即每走一步距离+1)。
- 如果
d[x] + 1 < d[y]
:- 发现了一条更短的路径到
y
。 - 更新
d[y] = d[x] + 1
,并重置dp[y] = dp[x]
(因为旧路径不再有效)。 - 将
y
加入队列,继续探索。
- 发现了一条更短的路径到
- 如果
d[x] + 1 == d[y]
:- 找到了一条等长的最短路径到
y
。 - 累加方案数:
dp[y] += dp[x]
(模p
防止溢出)。 - 无需重复入队(因为距离未变,BFS保证先到的最短路径已处理)。
- 找到了一条等长的最短路径到
- 如果
d[x] + 1 > d[y]
:- 当前路径比已知最短路径长,直接跳过。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 9;
const int p = 1e9 + 7;
vector<int> g[N];
// d[]表示从索引值城市到城市1的距离;dp[]表示从索引值城市到城市1最近的路径
int d[N], dp[N];
void bfs() {bitset<N> vis;queue<int> qu;qu.push(1);memset(d, 0x3f, sizeof d); //给每个城市最近距离初始化为无穷d[1] = 0;//1到第一个城市的距离为0dp[1] = 1; //到第一个城市方案数为1while(!qu.empty()) {//访问并取出队头 判断并标记为visitedint x = qu.front();qu.pop();if(vis[x]) continue;vis[x] = true;//找下一个城市y 判断d[y]与d[x]+1的关系for(const auto & y : g[x]) {//从城市1到城市y的距离比之前走过的远,不考虑if(d[x] + 1 > d[y]) continue;//找到另一条最短路径,累加方案数if(d[x] + 1 == d[y]) dp[y] = dp[y] + dp[x] % p;//找到一条更短的经过x y的路else d[y] = d[x] + 1, dp[y] = dp[x];qu.push(y);}}
}
int main() {int n, m;cin >> n >> m;//双向图for(int i = 1; i <= m; i++) {int a, b;cin >> a >> b;g[a].push_back(b);g[b].push_back(a);}bfs();cout << dp[n] << endl;return 0;
}
实例:
1 -- 2 -- 3 \ / 4
bfs过程:
-
从城市1出发,
d[1]=0
,dp[1]=1
。 -
遍历1的邻居
{2, 4}
- 更新
d[2]=1
,dp[2]=1
;d[4]=1
,dp[4]=1
。
- 更新
-
处理城市2:
-
邻居
{1, 3, 4}
- 1已访问(
d[1]=0
),跳过。 - 到3的“当前路径”长度
d[2]+1=2
,更新d[3]=2
,dp[3]=1
。 - 到4的“当前路径”长度
d[2]+1=2
,但d[4]=1
(更短),跳过。
- 1已访问(
-
-
处理城市4:
-
邻居
{1, 2}
- 1已访问,跳过。
- 到2的“当前路径”长度
d[4]+1=2
,但d[2]=1
(更短),跳过。
-
-
处理城市3:
- 邻居
{2}
,已处理。
- 邻居
最小生成树Kruskal
与Prim算法不同,该算法的核心思想是归并边,而Prim算法的核心思想是归并点。若边数远少于完全图,Kruskal比Prim算法更高效。
思想回顾:
步骤:
- 按照所有边权排序
- 从小到大遍历所有边(u,v),如果已联通就跳过,否则就选中(u,v),将其连通。(用到并查集)
模版题代码:旅行销售员
走完N个城市,每公里消耗1升油,找出所需油箱的最小容量。
#include <iostream>
#include <vector>
#include <algorithm> using namespace std;
using ll = long long; // 使用长整型存储权值 // 边结构体:起点x、终点y、权值c
struct Edge { ll x, y, c; // 重载<运算符,按权值升序排序 bool operator<(const Edge& u) const { return c < u.c; }
}; // 并查集:查找根节点(带路径压缩)
//目标:确定哪些节点属于同一个连通分量,它并不关心边的方向性
int root(vector<int>& pre, int x) { return pre[x] == x ? x : pre[x] = root(pre, pre[x]);
} void solve() { int n, m; // 节点数、边数 cin >> n >> m; // 初始化并查集 vector<int> pre(n + 1); for (int i = 1; i <= n; ++i) { pre[i] = i; // 初始时每个节点的父节点是自己 } // 读取所有边 vector<Edge> es; for (int i = 1; i <= m; ++i) { ll x, y, c; cin >> x >> y >> c; es.push_back({x, y, c}); } // 按边权升序排序 sort(es.begin(), es.end()); ll res = 0; // 记录MST中的最大边权 for (const auto& edge : es) { int x = edge.x; int y = edge.y; ll c = edge.c; // 若x和y不连通,则合并它们 if (root(pre, x) != root(pre, y)) { res = max(res, c); // 更新最大边权 pre[root(pre, x)] = root(pre, y); // 合并操作 } } cout << res << endl; // 输出结果
} int main() { int T = 0; // 测试数据组数 cin >> T; while (T--) { solve(); // 处理每组数据 } return 0;
}
最小生成树Prim
思想回顾:
与dijkstra很像,逐步扩大树中所含顶点的数目,直到遍及连通图的所有顶点。下面描述我们假设N = ( V , E ) 是连通网,T E 是N 上最小生成树中边的集合。
- 每次找出不再mst中且d[]最小的点x,d[x]就是选中的那条边的边权。
- 将x加入mst,并更新其所有出点y,
d[y]=min(d[y],w) //w为x到y的距离
- 如果d[y]变小,就加入到优先队列中作为可能的拓展点
mst使用bitset数组实现即可
代码模版题:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1E6 + 5;
ll n, m, inf = 1e9;
struct Edge {ll x, w;bool operator <(const Edge&u)const {return w > u.w; //小根堆}
};
//邻接表
vector<Edge>g[N];
//记录从起点(节点1)到各个节点的最小权重
ll d[N];
ll Prim() {//小根堆priority_queue<Edge>pq;bitset<N>vis;pq.push({1, d[1] = 0});ll res = 0;while(pq.size()) {//访问并取出元素x 判断并标记为visited//x为不在mst且权重最小的边ll x = pq.top().x;pq.pop();if(vis[x])continue;vis[x] = true;//更新mst最小权重总和res = max(res, d[x]);//遍历x所有邻接节点for(const auto & temp : g[x]) {ll y = temp.x;ll w = temp.w;//比较w和d[y] w 更小则更新d[y]if(w < d[y])pq.push({y, d[y] = w});}}return res;
}
void solve() {cin >> n >> m;//每次clear g[N]for(int i = 1; i <= n; i++)g[i].clear(), d[i] = inf;while(m--) {ll x, y, w;cin >> x >> y >> w;//输入带权值的双向边模版g[x].push_back({y, w});g[y].push_back({x, w});}cout << Prim() << endl;
}
int main() {int t;cin >> t;while(t--)solve();return 0;
}
相关文章:
树和图论(详细整理,简单易懂!)
树和图论 树的遍历模版 #include <iostream> #include <cstring> #include <vector> #include <queue> // 添加queue头文件 using namespace std;const int MAXN 100; // 假设一个足够大的数组大小 int ls[MAXN], rs[MAXN]; // 定义左右子树数…...
CWGAN-GP 原理及实现(pytorch版)
CWGAN-GP 一、CWGAN-GP 原理1.1 CWGAN-GP 的核心改进1.2 CWGAN-GP 的损失函数1.3 CWGAN-GP 的优势1.4 关键参数选择1.5 应用场景 二、CWGAN-GP 实现2.1 导包2.2 数据加载和处理2.3 构建生成器2.4 构建判别器2.5 训练和保存模型2.6 查看训练损失2.7 图片转GIF2.8 模型加载和推理…...
zookeeper平滑扩缩容
在进行ZooKeeper的扩容和缩容操作时,需要注意以下几点: 数据一致性 重要性:ZooKeeper的核心特性之一是保证数据的一致性。在操作过程中,必须确保数据的一致性,以避免数据丢失或损坏。 实现方式:ZooKeeper通…...
Github 热点项目 ChartDB AI自动导表结构+迁移脚本,3分钟生成专业数据库关系图
ChartDB堪称数据库设计神器!亮点①:动动手指输入SQL,秒出结构图,表关系一目了然,团队评审时再也不用画图两小时。亮点②:AI智能转换超贴心,MySQL转PostgreSQL只需点个按钮,跨平台迁移…...
RVOS-1.环境搭建与系统引导
0.环境搭建 riscv-operating-system-mooc: 开放课程《循序渐进,学习开发一个 RISC-V 上的操作系统》配套教材代码仓库。 mirror to https://github.com/plctlab/riscv-operating-system-mooc 在 Ubuntu 20.04 以上环境下我们可以直接使用官方提供的 GNU工具链和 QEM…...
Java List<JSONObject> 转换为 List<实体类>
可以使用 Fastjson 的 toJavaObject 方法直接转换,无需中间序列化步骤。以下是具体实现和注意事项: import com.alibaba.fastjson.JSONObject; import java.util.List; import java.util.stream.Collectors;public class Converter {public static List…...
CesiumEarth v1.12 更新,支持安卓平板离线浏览3DTiles格式的三维倾斜模型
CesiumEarth v1.12 更新 2025年4月8日 阅读需 1 分钟 发布时间:2025年04月08日 新增用户登录: 从1.12版本开始需要通过登录方可使用CesiumEarth 账号可以通过邮箱免费注册 后续将陆续发布云服务相关的功能 发布Desktop版本: Deskt…...
OpenEuler运维实战-系统资源监控与性能优化-CPU·内存·IO
CPU 基本概念定界定位思路常用CPU性能分析工具 基本概念 中央处理器(Central Processing Unit,简称CPU)是计算机的主要设备之一,其功能是解释计算机指令以及处理计算机软件中的数据。 物理核:可以真实看到的CPU核&…...
react实现SVG地图区域中心点呈现圆柱体,不同区域数据不同,圆柱体高度不同
效果图: 代码: import React, { useState, useEffect } from react;const InnerMongoliaMap () > {// 每个区域的数据(名称、中心坐标、圆柱体高度值)const [regionData, setRegionData] useState([{ id: "呼和浩特市…...
Qwen - 14B 怎么实现本地部署,权重参数大小:21GB
Qwen - 14B 权重参数大小:21GB 参数量与模型占用存储空间(GB)是不同概念。Qwen - 14B参数量约140亿 。其模型大小在不同精度下占用存储空间不同,如在一些资料中提到,Qwen - 14B在特定情况下占用空间约21GB 。实际存储…...
线程实现参考资料
参考 并发编程系列 - Java线程池监控及CompletableFuture详解_taskexecutor.execute没有执行如何监控到-CSDN博客 JAVA异步实现的四种方式_java异步编程的四种方法-CSDN博客 Java线程池深度解析与自定义实战-CSDN博客 Java8 CompletableFuture 异步多线程的实现_java_脚本之…...
python-63-前后端分离之图书管理系统的Flask后端
文章目录 1 flask后端1.1 数据库实例extension.py1.2 数据模型models.py1.3 .flaskenv1.4 app.py1.5 运行1.6 测试链接2 关键函数和文件2.1 请求视图类MethodView2.2 .flaskenv文件3 参考附录基于flask形成了图书管理系统的后端,同时对其中使用到的关键文件.flaskenv和函数类M…...
Qt网络编程之服务端
Qt网络编程之服务端 TCP(传输控制协议)是一种可靠的、面向流的、面向连接的传输协议。它特别适合连续的数据传输。 1. 主要类和函数 1.1 QTcpServer 监听函数: bool QTcpServer::listen(const QHostAddress &address QHostAddress::…...
案例-流量统计
1.建一个data目录,在data下建log.txt文件 输入手机号码 上行流量 下行流量 2.在com.example.flow下建四个Java类3.flowBean flowMapper flowReducer flowDriver...
开源身份和访问管理方案之keycloak(二)管理员引导和恢复
文章目录 开源身份和访问管理方案之keycloak(二)管理员引导和恢复管理员引导和恢复在 Keycloak 启动时引导临时管理员帐户对于恢复丢失的管理员访问权限使用专用命令引导管理员用户或服务帐户创建一个管理员用户创建一个服务账号重新获得对具有更高安全性…...
TCP,UDP协议和域名地址
1.TCP(传输控制协议)是面向连接,UDP(用户数据报协议)是无连接的 2.应用层:FTP,HTTP,SMTP,TELNET,DNS,TFTP 传输层;TCP,UDP 网际层:IP,ICMP,ARP,RARP 3.TCP21:20端口数据传输;21端…...
算法进阶指南 分形
问题描述 分形,具有以非整数维形式充填空间的形态特征。通常被定义为: “一个粗糙或零碎的几何形状,可以分成数个部分,且每一部分都(至少近似地)是整体缩小后的形状”,即具有自相似的性质。 现…...
2025年 npm淘宝镜像最新地址
查看当前镜像 npm config get registry 切换陶宝镜像源 npm config set registry https://registry.npmmirror.com/ 验证npm镜像源是否切换成功 npm config get registry 如果返回的地址是https://registry.npmmirror.com/,那么说明你已经成功切换到淘宝的npm…...
0基础 | 硬件 | LM386芯片
LM386芯片:音频功率放大器芯片 内部集成三极管功能将微弱信号放大20-200倍,并且驱动内阻为8Ω的扬声器注意CD系列芯片,内部集成MOS管 LM386特性 LM386主要由以下三个部分组成 内部电路 差分输入 差分输入 多个三极管左右对称,形…...
Spring Boot集成APK Parser库实现APK文件解析
目录 1. 添加依赖 2. 创建APK解析服务 3. 创建控制器 4. 测试 注意事项 在Spring Boot项目中集成APK Parser库并解析APK文件,可以按照以下步骤进行操作: 1. 添加依赖 在项目的pom.xml文件中添加apk-parser库的依赖: <dependency&…...
java基础 迭代Iterable接口以及迭代器Iterator
Itera迭代 Iterable < T>迭代接口(1) Iterator iterator()(2) forEach(Consumer<? super T> action)forEach结合Consumer常见场景forEach使用注意细节 (3)Spliterator spliterator() Iterator< T>迭代器接口如何“接收” Iterator<T>核心方法迭代器的…...
Linux: network: tcpdump: packets dropped by kernel
文章目录 最近遇到一个问题原因libpcap/tcpdump 接口linux/libpcap 接口内核的处理原因可能有以下几种:解决方法:man pcap_stats最近遇到一个问题 tcpdump命令显示有dropped的包,而且是被内核drop的。 [root@-one-01 ~]# tcpdump -i any udp and port 8080 -v -w /root/udp…...
TCP三次握手和TCP四次挥手
一 TCP三次握手 TCP建立连接的过程叫做握手,握手需要客户端和服务器之间交换三个TCP报文段。如图所示,假设主机A为TCP客户端,主机B为TCP服务端。在最初时间,两端的TCP进程都是处于CLOSED状态 (1)主机A主动…...
博途 TIA Portal之1200做主站与调试助手的TCP通讯
博途支持的通讯非常多,常见的有S7、TCP/IP,UDP等等,本文将演示TCP的通讯,通讯的双方是1200PLC和调试助手之间,编程采用ST语言。 1、硬件准备 1200PLC一台,带调试助手的PC机一台,调试助手是我经…...
第十天 - socket编程基础 - TCP/UDP服务开发 - 练习:简易端口扫描器
Python网络编程入门:从Socket到端口扫描器实战 一、前言:为什么要学网络编程? 在这个万物互联的时代,掌握网络编程技术就像拥有了一把打开互联网世界的钥匙。无论是开发聊天软件、网络游戏,还是构建分布式系统&#…...
欧税通香港分公司办公室正式乔迁至海港城!
3月20日,欧税通香港分公司办公室正式乔迁至香港油尖旺区的核心商业区海港城!左手挽着内地市场,右手牵起国际航道——这波乔迁选址操作堪称“地理课代表”! 乔迁仪式秒变行业大联欢!感谢亚马逊合规团队、亚马逊云、阿里国际站、Wayfair、coupang、美客多…...
Maven的安装配置-项目管理工具
各位看官,大家早安午安晚安呀~~~ 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连,小编尽全力做到更好 欢迎您分享给更多人哦 今天我们来学习:Maven的安装配置-项目管理工具 目录 1.什么是Maven?Maven用来干什么的?…...
【Linux篇】缓冲区的工作原理:如何影响你程序的输入输出速度
从内存到磁盘:缓冲区如何提升文件I/O效率 一. 缓冲区1.1 什么是缓冲区1.2 为什么要引入缓冲区1.3 缓冲区类型1.4 FILE1.4.1 基本概念1.4.2 FILE 结构体的作用1.4.3 FILE 的工作机制 二. 最后 在程序开发中,缓冲区是一个经常被提及却不容易深入理解的概念…...
编写junit测试类 import org.junit.Test;
1. 添加依赖 <!-- Spring Boot Starter Test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> 2. …...
初识数据结构——深入理解LinkedList与链表:吃透LinkedList与链表的终极指南
📌 深入理解LinkedList与链表:从原理到实战应用 🌟 引言 在Java集合框架中,LinkedList和ArrayList是最常用的两种列表结构。它们各有优劣,适用于不同的场景。本文将带你深入探索LinkedList的底层实现——链表&#x…...
C++版Qt之登录界面设计
在C开发中,使用Qt框架可以快速构建美观且功能强大的GUI应用程序。本文将介绍如何设计一个漂亮的登录界面,包括账号和密码输入框,并确保只有验证成功后才能进入主窗口。 项目结构 文件列表 LoginDialog.h:登录对话框的头文件Logi…...
Java logback框架日志输出中文乱码的解决方案(windows)
在Java开发中,日志记录是一个重要的部分,它可以帮我们定位问题、运行时监控、错误排查与故障恢复。但是,在有些情况下,使用Logback记录的中文日志会出现乱码,这会影响日志的可读性,给维护带来麻烦。本文将探…...
【c++】c/c++内存管理
小编个人主页详情<—请点击 小编个人gitee代码仓库<—请点击 c系列专栏<—请点击 倘若命中无此运,孤身亦可登昆仑,送给屏幕面前的读者朋友们和小编自己! 目录 前言一、c语言内存管理二、一图搞懂c/c中的程序内存区域划分三、c内存管理1. new和d…...
【C++】Stack Queue 仿函数
📝前言: 这篇文章我们来讲讲STL中的stack和queue。因为前面我们已经有了string、vector和list的学习基础,所以这篇文章主要关注一些stack和queue的细节问题,以及了解一下deque(缝合怪)和priority_queue &am…...
Python:基于Flask框架的数据可视化系统
以下是一个基于Flask框架的数据可视化系统代码示例,包含核心功能实现: python 复制 # app.py 后端核心代码 from flask import Flask, render_template, jsonify import sqlite3 from collections import defaultdict import jieba import reapp Fla…...
JVM即时编译(JIT)
JVM基础回顾 Java 作为一门高级程序语言,由于它自身的语言特性,它并非直接在硬件上运行,而是通过编译器(前端编译器)将 Java 程序转换成该虚拟机所能识别的指令序列,也就是字节码,然后运行在虚拟机之上的;…...
JVM高阶架构:并发模型×黑科技×未来趋势解析
🚀前言 “你是否还在为synchronized锁竞争头疼?是否好奇ZGC如何实现亚毫秒停顿?Java的未来将走向何方? 本文将带你深入JVM最硬核的三大领域: 并发模型:揭秘happens-before如何保证多线程安全(…...
Java的JDK、JRE、JVM关系与作用
Java的JDK、JRE、JVM关系与作用 java中的JDK、JRE和JVM是三个核心组件,各自承担不同角色,且存在层级依赖关系 1. JVM(Java Virtual Machine,Java虚拟机) 是什么: JVM是虚拟的计算机,能够执行…...
XMLHttpRequest vs Fetch API:一场跨越时代的“浏览器宫斗剧“
## 序幕:两个API的"身世之谜" 在Web开发的江湖里,XMLHttpRequest(简称XHR)就像一位身经百战的老将,而Fetch API则是手持光剑的绝地武士。让我们先来段"DNA检测": - **XHR(…...
Windows Anaconda使用Sentence-BERT获取句子向量
1、安装Anaconda: Anaconda是一个流行的Python数据科学平台,它包含了许多科学计算和数据分析的库,包括transformers和sentence_transformers。虽然不是必需的,但使用Anaconda可以简化环境管理和依赖安装的过程。 可以从Anaconda官…...
【Java设计模式】第5章 工厂方法模式讲解
5. 工厂方法模式 5.1 工厂方法讲解 定义:定义一个创建对象的接口,由子类决定实例化的类,将对象创建延迟到子类。适用场景: 创建对象需要大量重复代码。客户端不依赖具体产品的创建细节。优点: 符合开闭原则,新增产品只需扩展子类。客户端仅依赖抽象接口,不依赖具体实现…...
结合 Less + CSS 变量实现切换主题
一开始的思路是通过 Less 变量作用范围 来切换 light 和 dark 主题,但 Less 本身不会动态监听类名变化,所以直接这样写是 不可行的,因为 Less 是 预处理语言,它在编译阶段就确定了 color 的值,而不是在运行时动态切换。…...
数据分析之python处理常用复杂转置数据
前段时间根据需求配合ai写了个转置excel代码,挺好用的,而且可以选择excel,不局限于excel存在哪个地方,都可以转置,但是转置后的excel记得要先创建放在转置文件的目录下。 原本的数据长这样 转置后则可以变为这样&…...
未来杭州:科技与诗意的时空交响曲
故事背景 故事发生在中国浙江杭州的未来科技时代,通过六个充满未来感的场景展现传统文明与尖端科技的完美融合。全篇无人物角色,专注于构建兼具东方美学与赛博朋克风格的沉浸式景观。 故事内容 从晨雾中浮现全息诗句的西湖,到吞吐智能包裹的运…...
彩虹表是什么
彩虹表是一种用于破解加密散列函数的预计算表,主要用于破解密码的哈希值。以下是关于加密文件与彩虹表的相关信息: 彩虹表的原理 • 时空折中:彩虹表基于时空折中理论,通过预先计算并存储大量可能的密码及其哈希值,减少…...
[BreachCTF 2025]
周末的这个居然一个密码都不会,作了4个pwn,给原码看着真方便 FSWn3d #define _GNU_SOURCE #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <unistd.h>char buffer[152…...
行业案例 | 印度航空借助 Azure AI,提升智能航空体验
自2022年塔塔集团(Tata Group)接管以来,印度航空启动了全面现代化升级,不仅豪掷470架新飞机订单以重塑“以人为本”的品牌形象,更将数字化作为核心战略——将所有工作负载(包括全新官网)从本地数…...
【Java设计模式】第7章 建造者模式讲解
7-1 建造者模式讲解 1. 定义与类型 定义: 将复杂对象的构建与表示分离,使相同构建过程可创建不同表示。类型: 创建型模式。通俗解释: 分步构建含多组件的对象,流程固定但顺序灵活(如做菜时放盐顺序可变)。2. 适用场景 对象内部结构复杂(多属性或多步骤)。需将对象创建与…...
鸿蒙ArkTS实战:从零打造智能表达式计算器(附状态管理+路由传参核心实现)
还在为组件状态混乱、页面跳转丢参数而头疼? 这篇博客将揭秘如何用鸿蒙ArkTS打造一个漂亮美观的智能计算器: ✅ 输入完整表达式,秒出结果——字符串切割简单计算 ✅ 状态管理黑科技——Provide/Consume 实现跨组件实时响应 ✅ 路由传参实战—…...
虚拟机上安装openEuler和openGauss数据库
1.虚拟机版本选择VM 16 PRO 2.openEuler版本选择openEuler-22.03-LTS-SP4-x86_64 下载地址:https://mirrors.aliyun.com/openeuler/openEuler-22.03-LTS-SP4/ISO/x86_64/openEuler-22.03-LTS-SP4-x86_64-dvd.iso 3.虚拟机安装openEuler过程: 4.安装ope…...