图的概念、性质和存储与简单遍历

前置知识:树的基本概念及性质

为了保证学习效果,请保证已经掌握前置知识之后,再来学习本章节!如果在阅读中遇到困难,也可以回到前面章节查阅。

学习目标

  • 掌握图的基本概念
  • 掌握图的一些性质

图的概念

基本概念

图 (Graph) 是一个二元组 𝐺=(𝑉(𝐺),𝐸(𝐺))G=(V(G),E(G)) 。其中 𝑉(𝐺)V(G) 是非空集,称为 点集 (Vertex set) ,对于 𝑉V 中的每个元素,我们称其为 顶点 (Vertex) 或 节点 (Node) ,简称  ; 𝐸(𝐺)E(G) 为 𝑉(𝐺)V(G) 各结点之间边的集合,称为 边集 (Edge set) 。

常用 𝐺=(𝑉,𝐸)G=(V,E) 表示图。

当 𝑉,𝐸V,E 都是有限集合时,称 𝐺G 为 有限图 。

当 𝑉V 或 𝐸E 是无限集合时,称 𝐺G 为 无限图 。

图有多种,包括 无向图 (Undirected graph) , 有向图 (Directed graph) , 混合图 (Mixed graph) 等

若 𝐺G 为无向图,则 𝐸E 中的每个元素为一个无序二元组 (𝑢,𝑣)(u,v) ,称作 无向边 (Undirected edge) ,简称 边 (Edge) ,其中 𝑢,𝑣∈𝑉u,v∈V 。设 𝑒=(𝑢,𝑣)e=(u,v) ,则 𝑢u 和 𝑣v 称为 𝑒e 的 端点 (Endpoint) 。

若 𝐺G 为混合图,则 𝐸E 中既有向边,又有无向边。

若 𝐺G 的每条边 𝑒𝑘=(𝑢𝑘,𝑣𝑘)ek​=(uk​,vk​) 都被赋予一个数作为该边的  ,则称 𝐺G 为 赋权图 。如果这些权都是正实数,就称 𝐺G 为 正权图 。

形象地说,图是由若干点以及连接点与点的边构成的。

图片

图上的关系

点与点——邻接

在无向图 𝐺=(𝑉,𝐸)G=(V,E) 中,对于两顶点 𝑢u 和 𝑣v ,若存在边 (𝑢,𝑣)(u,v) ,则称 𝑢u 和 𝑣v 是 相邻(邻接)的 。

一个顶点 𝑣∈𝑉v∈V 的 邻域 (Neighborhood) 是所有与之相邻的顶点所构成的集合,记作 𝑁(𝑣)N(v) 。

PS:邻接表存储的就是邻域,并且由此得名。

点与边——关联

在无向图 𝐺=(𝑉,𝐸)G=(V,E) 中,若点 𝑣v 是边 𝑒e 的一个端点,则称 𝑣v 和 𝑒e 是 关联的

度数

与一个顶点 𝑣v 关联的边的条数称作该顶点的 度 (Degree) ,记作 𝑑(𝑣)d(v) 。特别地,对于边 (𝑣,𝑣)(v,v) ,则每条这样的边要对 𝑑(𝑣)d(v) 产生 22 的贡献。

对于无向简单图,有 𝑑(𝑣)=∣𝑁(𝑣)∣d(v)=∣N(v)∣ 。

握手定理(又称图论基本定理):对于任何无向图 𝐺=(𝑉,𝐸)G=(V,E) ,有 ∑𝑣∈𝑉𝑑(𝑣)=2∣𝐸∣∑v∈V​d(v)=2∣E∣ ,即无向图中结点度数的总和等于边数的两倍。有向图中结点的入度之和等于出度之和等于边数。

推论: 在任意图中,度数为奇数的点必然有偶数个。

证明:反证法

简单图

自环 (Loop) :对 𝐸E 中的边 𝑒=(𝑢,𝑣)e=(u,v) ,若 𝑢=𝑣u=v ,则 𝑒e 被称作一个自环。

重边/平行边 (Multiple edge) :若 𝐸E 中存在两个完全相同的元素(边) 𝑒1,𝑒2e1​,e2​ ,则它们被称作(一组)重边。

简单图 (Simple graph) :若一个图中 没有自环和重边,它被称为简单图。非空简单无向图中一定存在度相同的结点。

如果一张图中有自环或重边,则称它为 多重图 (Multigraph) 。

图片

​ 在无向图中 (𝑢,𝑣)(u,v) 和 (𝑣,𝑢)(v,u) 算一组重边,而在有向图中, 𝑢→𝑣u→v 和 𝑣→𝑢v→u 不为重边。

​ 在题目中,如果没有特殊说明,是可以存在自环和重边的,在做题时需特殊考虑。

路径

途径 (Walk) / 链 (Chain) :一个点和边的交错序列,其中首尾是点—— 𝑣0,𝑒1,𝑣1,𝑒2,𝑣2,…,𝑒𝑘,𝑣𝑘v0​,e1​,v1​,e2​,v2​,…,ek​,vk​ ,有时简写为 𝑣0→𝑣1→𝑣2→⋯→𝑣𝑘v0​→v1​→v2​→⋯→vk​ 。其中 𝑒𝑖ei​ 的两个端点分别为 𝑣𝑖−1vi−1​ 和 𝑣𝑖vi​ 。通常来说,边的数量 𝑘k 被称作这条途径的 长度 (如果边是带权的,长度通常指路径上的边权之和,题目中也可能另有定义)。(以下设 𝑤=[𝑣0,𝑒1,𝑣1,𝑒2,𝑣2,⋯,𝑒𝑘,𝑣𝑘]w=[v0​,e1​,v1​,e2​,v2​,⋯,ek​,vk​] 。)

迹 (Trail) :对于一条途径 𝑤w ,若 𝑒1,𝑒2,⋯,𝑒𝑘e1​,e2​,⋯,ek​ 两两互不相同,则称 𝑤w 是一条迹。

路径 (Path) (又称 简单路径 (Simple path) ):对于一条迹 𝑤w ,除了 𝑣0v0​ 和 𝑣𝑘vk​ 允许相同外,其余点两两互不相同,则称 𝑤w 是一条路径。

回路 (Circuit) :对于一个迹 𝑤w ,若 𝑣0=𝑣𝑘v0​=vk​ ,则称 𝑤w 是一个回路。

环/圈 (Cycle) (又称 简单回路/简单环 (Simple circuit) ):对于一条简单路径 𝑤w ,若 𝑣0=𝑣𝑘v0​=vk​ ,则称 𝑤w 是一个环。

!!! warning
关于路径的定义在不同地方可能有所不同,如,“路径”可能指本文中的“途径”,“环”可能指本文中的“回路”。如果在题目中看到类似的词汇,且没有“简单路径”/“非简单路径”(即本文中的“途径”)等特殊说明,最好询问一下具体指什么。

连通

无向图

对于一张无向图 𝐺=(𝑉,𝐸)G=(V,E) ,对于 𝑢,𝑣∈𝑉u,v∈V ,若存在一条途径使得 𝑣0=𝑢,𝑣𝑘=𝑣v0​=u,vk​=v ,则称 𝑢u 和 𝑣v 是 连通的 (Connected) 。由定义,任意一个顶点和自身连通,任意一条边的两个端点连通。

若无向图 𝐺=(𝑉,𝐸)G=(V,E) ,满足其中任意两个顶点均连通,则称 𝐺G 是 连通图 (Connected graph) , 𝐺G 的这一性质称作 连通性 (Connectivity) 。

若 𝐻H 是 𝐺G 的一个连通子图,且不存在 𝐹F 满足 𝐻⊊𝐹⊆𝐺H⊊F⊆G 且 𝐹F 为连通图,则 𝐻H 是 𝐺G 的一个 连通块/连通分量 (Connected component) (极大连通子图)。

图片

图片

有向图

对于一张有向图 𝐺=(𝑉,𝐸)G=(V,E) ,对于 𝑢,𝑣∈𝑉u,v∈V ,若存在一条途径使得 𝑣0=𝑢,𝑣𝑘=𝑣v0​=u,vk​=v ,则称 𝑢u 可达 𝑣v 。由定义,任意一个顶点可达自身,任意一条边的起点可达终点。(无向图中的连通也可以视作双向可达。)

若一张有向图的节点两两互相可达,则称这张图是 强连通的 (Strongly connected) 。

图片

若一张有向图的边替换为无向边后可以得到一张连通图,则称原来这张有向图是 弱连通的 (Weakly connected) 。

与连通分量类似,也有 弱连通分量 (Weakly connected component) (极大弱连通子图)和 强连通分量 (Strongly Connected component) (极大强连通子图)。

图片

𝑛n 个顶点的强连通图最多 𝑛(𝑛−1)n(n−1) 条边,最少 𝑛n 条边。

图片

图的连通性也是竞赛的一个常见考点,相关算法请后面将学习,现在先理解其概念即可。

稀疏图/稠密图

若一张图的边数远小于其点数的平方,那么它是一张 稀疏图 (Sparse graph) 。

若一张图的边数接近其点数的平方,那么它是一张 稠密图 (Dense graph) 。

这两个概念并没有严格的定义,一般用于讨论 时间复杂度 为 𝑂(∣𝑉∣2)O(∣V∣2) 的算法与 𝑂(∣𝐸∣)O(∣E∣) 的算法的效率差异(在稠密图上这两种算法效率相当,而在稀疏图上 𝑂(∣𝐸∣)O(∣E∣) 的算法效率明显更高)。

特殊的图

完全图

若无向简单图 𝐺G 满足任意不同两点间均有边,则称 𝐺G 为 完全图 (Complete graph) , 𝑛n 阶完全图记作 𝐾𝑛Kn​ 。若有向图 𝐺G 满足任意不同两点间都有两条方向不同的边,则称 𝐺G 为 有向完全图 (Complete digraph) 。

图片

环图/圈图

若无向简单图 𝐺=(𝑉,𝐸)G=(V,E) 的所有边恰好构成一个圈,则称 𝐺G 为 环图/圈图 (Cycle graph) , 𝑛n ( 𝑛≥3n≥3 ) 阶圈图记作 𝐶𝑛Cn​ 。易知,一张图为圈图的充分必要条件是,它是 22 - 正则连通图。

星图/菊花图

若无向简单图 𝐺=(𝑉,𝐸)G=(V,E) 满足,存在一个点 𝑣v 为支配点,其余点之间没有边相连,则称 𝐺G 为 星图/菊花图 (Star graph) , 𝑛+1n+1 ( 𝑛≥1n≥1 ) 阶星图记作 𝑆𝑛Sn​ 。

轮图

若无向简单图 𝐺=(𝑉,𝐸)G=(V,E) 满足,存在一个点 𝑣v 为支配点,其它点之间构成一个圈,则称 𝐺G 为 轮图 (Wheel Graph) , 𝑛+1n+1 ( 𝑛≥3n≥3 ) 阶轮图记作 𝑊𝑛Wn​ 。

image-20210328095407460

若无向简单图 𝐺=(𝑉,𝐸)G=(V,E) 的所有边恰好构成一条简单路径,则称 𝐺G 为 链 (Chain/Path Graph) , 𝑛n 阶的链记作 𝑃𝑛Pn​ 。易知,一条链由一个圈图删去一条边而得。

如果一张无向连通图不含环,则称它是一棵 树 (Tree) 。相关内容详见 树基础 。

补图

对于无向简单图 𝐺=(𝑉,𝐸)G=(V,E) ,它的 补图 (Complement graph) 指的是这样的一张图:记作 𝐺ˉGˉ ,满足 𝑉(𝐺ˉ)=𝑉(𝐺)V(Gˉ)=V(G) ,且对任意节点对 (𝑢,𝑣)(u,v) , (𝑢,𝑣)∈𝐸(𝐺ˉ)(u,v)∈E(Gˉ) 当且仅当 (𝑢,𝑣)∉𝐸(𝐺)(u,v)∈/E(G) 。

图片

反图

对于有向图 𝐺=(𝑉,𝐸)G=(V,E) ,它的 反图 (Transpose Graph) 指的是点集不变,每条边反向得到的图,即:若 𝐺G 的反图为 𝐺′=(𝑉,𝐸′)G′=(V,E′) ,则 𝐸′={(𝑣,𝑢)∣(𝑢,𝑣)∈𝐸}E′={(v,u)∣(u,v)∈E} 。

平面图

如果一张图可以画在一个平面上,且没有两条边在非端点处相交,那么这张图是一张 平面图 (Planar graph) 。一张图的任何子图都不是 𝐾5K5​ 或 𝐾3,3K3,3​ 是其为一张平面图的充要条件。对于简单连通平面图 𝐺=(𝑉,𝐸)G=(V,E) 且 𝑉≥3V≥3 , ∣𝐸∣≤3∣𝑉∣−6∣E∣≤3∣V∣−6 。

image-20210328095019950

 

学习目标

  • 掌握图的四种存储方法的代码实现
  • 理解图的四种存储方法各自的时间空间复杂度
  • 能够根据题目的要求和数据范围,选择合适存图方式

图的逻辑结构

一张图是由节点构成的,一个无向图如下图所示:

图片

什么叫 「逻辑结构」?就是说为了方便研究,我们把图 抽象 成这个样子。

根据这个逻辑结构,我们可以认为每个节点的实现如下:

// 图节点的逻辑结构
struct node {int data;                 // 存当前结点信息vector<int> neighbors;  // 存邻接的所有结点
}

看到这个实现,你有没有很熟悉?它和我们之前说的多叉树节点几乎完全一样:

// 树节点的逻辑结构
struct node {int data;                 // 存当前结点信息vector<int> son;        // 存所有的子结点
}

Copy

不过呢,上面的这种实现是「逻辑上的」,实际上我们很少用这个node类实现图,而是用接下来介绍的几种方法去存储。其中包含我们前面经常提到的 邻接表和邻接矩阵

图的存储方法

接下来描述图的具体四种存储方式,这四种方式是我们今后和图这种数据结构打交道的接口,请一定要掌握。

首先约定,用 𝑛n 代指图的点数,用 𝑚m 代指图的边数,用 𝑑+(𝑢)d+(u) 代指点 𝑢u 的出度,即以 𝑢u 为出发点的边数。

直接存边

方法

使用一个数组来存边,数组中的每个元素都包含一条边的起点与终点(带边权的图还包含边权)。(或者使用多个数组分别存起点,终点和边权。)

#include <iostream>
#include <vector>
using namespace std;struct Edge {int u, v, w;   // 一条边的 起点、终点、权值
};int n, m;
vector<Edge> e;
vector<bool> vis;// 函数功能:判断 u,v 之间有没有边
bool find_edge(int u, int v) {for (int i = 1; i <= m; ++i) {if (e[i].u == u && e[i].v == v) {return true;}}return false;
}// 遍历图
void dfs(int u) {if (vis[u]) return;vis[u] = true;for (int i = 1; i <= m; ++i) {if (e[i].u == u) {dfs(e[i].v);}}
}int main() {cin >> n >> m;// 初始化 vector 数组,也可以将 vis 定义成: “bool vis[N];” 以省去初始化。下同vis.resize(n + 1, false);e.resize(m + 1);for (int i = 1; i <= m; ++i) cin >> e[i].u >> e[i].v >> e[i].w;return 0;
}

复杂度

查询是否存在某条边: 𝑂(𝑚)O(m) 。

遍历一个点的所有出边: 𝑂(𝑚)O(m) 。

遍历整张图: 𝑂(𝑛𝑚)O(nm) 。

空间复杂度: 𝑂(𝑚)O(m) 。

应用

由于直接存边的遍历效率低下,一般不用于遍历图。

在 Kruskal 算法中,由于需要将边按边权排序,需要直接存边。

在有的题目中,需要多次建图(如建一遍原图,建一遍反图),此时既可以使用多个其它数据结构来同时存储多张图,也可以将边直接存下来,需要重新建图时利用直接存下的边来建图。

邻接矩阵

方法

使用一个二维数组 g 来存边,其中 g[u][v] 为 1 表示存在 𝑢u 到 𝑣v 的边,为 0 表示不存在。

如果是带边权的图,可以在 g[u][v] 中存储 𝑢u 到 𝑣v 的边的边权,0 表示没有连接,其他值表示权重。

如果是无向图,则将一条无向边拆成两条方向相反的边即可。(所谓的「无向」,也就等同于「双向」)

#include <iostream>
#include <vector>
using namespace std;const int N = 1e5+5;
int n, m;
bool vis[N];
bool g[N][N];bool find_edge(int u, int v) { return g[u][v]; }void dfs(int u) {if (vis[u]) return;vis[u] = true;for (int v = 1; v <= n; ++v) {if (g[u][v]) {dfs(v);}}
}int main() {cin >> n >> m;fill_n(vis, N, false);  // 将 vis 数组清 false,类似 memsetfill_n(g, N*N, false);for (int i = 1; i <= m; ++i) {int u, v;cin >> u >> v;g[u][v] = true;   // u->v 有条单向边// 如果是双向边// g[u][v] = g[v][u] = true;}return 0;
}

复杂度

查询是否存在某条边: 𝑂(1)O(1) 。

遍历一个点的所有出边: 𝑂(𝑛)O(n) 。

遍历整张图: 𝑂(𝑛2)O(n2) 。

空间复杂度: 𝑂(𝑛2)O(n2) 。

应用

邻接矩阵只适用于没有重边(或重边可以忽略)的情况。

其最显著的优点是可以 𝑂(1)O(1) 查询一条边是否存在。

由于邻接矩阵在稀疏图上效率很低(尤其是在点数较多的图上,空间无法承受),所以一般只会 在稠密图上使用邻接矩阵。并且,在稠密图上使用邻接矩阵的运行效率远高于邻接表,这是因为 CPU 中顺序访问的速度是远高于随机访问的(缓存命中)。

图片

邻接表

方法

使用一个支持动态增加元素的数据结构构成的数组,如 vector<int> g[N] 来存边,其中 g[u] 存储的是点 𝑢u 的所有出边的相关信息(终点、边权等)。

#include <iostream>
#include <vector>
using namespace std;const int N = 1e5+5;
int n, m;
bool vis[N];
vector<int> g[N];bool find_edge(int u, int v) {for (int i = 0; i < g[u].size(); ++i) {if (g[u][i] == v) {return true;}}return false;
}void dfs(int u) {if (vis[u]) return;vis[u] = true;for (int i = 0; i < g[u].size(); ++i) dfs(g[u][i]);
}int main() {cin >> n >> m;vis.resize(n + 1, false);g.resize(n + 1);for (int i = 1; i <= m; ++i) {int u, v;cin >> u >> v;g[u].push_back(v);// 如果是无向图,还须:// g[v].push_back(u);}return 0;
}

复杂度

查询是否存在 𝑢u 到 𝑣v 的边: 𝑂(𝑑+(𝑢))O(d+(u)) (如果事先进行了排序就可以使用 二分查找 做到 𝑂(log⁡(𝑑+(𝑢)))O(log(d+(u))) )。

遍历点 𝑢u 的所有出边: 𝑂(𝑑+(𝑢))O(d+(u)) 。

遍历整张图: 𝑂(𝑛+𝑚)O(n+m) 。

空间复杂度: 𝑂(𝑚)O(m) 。

应用

存各种图都很适合,除非有特殊需求(如需要快速查询一条边是否存在,且点数较少,可以使用邻接矩阵)。

尤其适用于需要对一个点的所有出边进行排序的场合。

链式前向星

方法

本质上是用链表实现的邻接表,示例代码如下:

#include <iostream>
#include <vector>
using namespace std;const int N = 1e5+5;
int n, m;bool vis[N];
int head[N], nxt[N], to[N], cnt;     // 链式前向星三要素void add(int u, int v) {     // 添加一条 u->v 的边nxt[++cnt] = head[u];    // cnt 这条边的后继(同是 u 的出边的上一条边)to[cnt] = v;             // 当前边的终点是 vhead[u] = cnt;           // 起点 u 的第一条边放到了下标 cnt 处(其实是最后一条)
}bool find_edge(int u, int v) {for (int i = head[u]; ~i; i = nxt[i]) {  // ~i 表示 i != -1if (to[i] == v) {return true;}}return false;
}void dfs(int u) {if (vis[u]) return;vis[u] = true;cout << u << ' ';for (int i = head[u]; ~i; i = nxt[i])dfs(to[i]);
}int main() {cin >> n >> m;fill_n(vis, N, false);fill_n(head, N, -1);for (int i = 1; i <= m; ++i) {int u, v;cin >> u >> v;add(u, v);}dfs(1);return 0;
}

如果图是赋权图,即边带有权重时,此时数组定义过多,也可以写成结构体去保存,参考代码如下:

#include<bits/stdc++.h>
using namespace std;const int N = 1e5;    //点数最大值
int n, m;             //n个点,m条边
int head[N], cnt = -1;     //head[i],表示以i为起点的第一条边在边集数组的位置(编号)struct Edge
{int to, w, next;   // 终点,边权,同起点的上一条边的编号
}edge[N];//边集void add_edge(int u, int v, int w)// 加边,u 起点,v 终点,w 边权
{edge[++cnt].next = head[u];    // 以u为起点上一条边的编号,也就是与这个边起点相同的上一条边的编号edge[cnt].to = v;          // 终点edge[cnt].w = w;             // 权值head[u] = cnt;               // 更新以u为起点上一条边的编号
}
int main()
{cin >> n >> m;int u, v, w;fill_n(head, N, -1);for (int i = 1; i <= m; i++) // 输入m条边{cin >> u >> v >> w;add_edge(u, v, w);       // 加边// 加双向边// add_edge(u, v, w);// add_edge(v, u, w);}// 输出每个结点的出边for (int i = 1; i <= n; i++){cout << i << endl;for (int j = head[i]; ~j; j = edge[j].next)  // 遍历以 i为起点的边{cout << i << " " << edge[j].to << " " << edge[j].w << endl;}cout << endl;}return 0;
}
/*
5 7
1 2 1
2 3 2
3 4 3
1 3 4
4 1 5
1 5 6
4 5 7
*/

复杂度

查询是否存在 𝑢u 到 𝑣v 的边: 𝑂(𝑑+(𝑢))O(d+(u)) 。

遍历点 𝑢u 的所有出边: 𝑂(𝑑+(𝑢))O(d+(u)) 。

遍历整张图: 𝑂(𝑛+𝑚)O(n+m) 。

空间复杂度: 𝑂(𝑚)O(m) 。

应用

注意:利用链式前向星遍历的边的顺序和输入顺序是相反的!

存各种图都很适合,但是缺点也很明显, 不能快速查询一条边是否存在,也不能方便地对一个点的出边进行排序

优点是边是带编号的,有时会非常有用,而且如果边是从数组的偶数位开始存储( 按上面示例代码写法是从 0 开始存储的,cnt 的初始值为 -1),存双向边时 i ^ 1 即是 i 的反边(常用于网络流 )。

总结

图的存储方法比较多,每种方法各有优缺点,对比如下:

直接存边邻接矩阵邻接表链式前向星
使用场合需要将边按边权排序时;需要重新建图时利用直接存下的边来建图只适用于没有重边(或重边可以忽略)的情况;可以 𝑂(1)O(1) 查询边;在稠密图上效率很高消耗空间较小,各种场合都适用,尤其适用于需要对点的出边排序的场合消耗空间小,各种场合都适用
缺点遍历效率低下,一般不用于遍历图只适用于没有重边(或重边可以忽略)的情况。需熟练掌握 vector 操作?不能迅速查询边和对一个点的出边排序

总的来说,就是:

  1. 需要对所有边进行排序时,直接存边;
  2. 图很稠密,用邻接矩阵;
  3. 其他一般情况,用邻接表或链式前向星都可以。

请在理解各种方法的优缺点并掌握其代码实现以后,面对具体问题应思考选择合适的方法。

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

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

相关文章

Pytorch如何计算网络参数

方法一. 利用pytorch自身 PyTorch是一个流行的深度学习框架&#xff0c;它允许研究人员和开发者快速构建和训练神经网络。计算一个PyTorch网络的参数量通常涉及两个步骤&#xff1a;确定网络中每个层的参数数量&#xff0c;并将它们加起来得到总数。 以下是在PyTorch中计算网…

如何在 CloudFlare 里屏蔽/拦截某个 IP 或者 IP 地址段

最近除了接的 CloudFlare 代配置订单基本很少折腾自己的 CloudFlare 配置了,今天给大家简单的讲解一下如何在 CloudFlare 里屏蔽/拦截 IP 地址和 IP 地址段,虽然明月一直都很反感针对 IP 的屏蔽拦截,但不得不说有时候还是很有必要的。并且,既然可以拦截屏蔽 IP 自然也可以但…

鸿蒙内核源码分析(VFS篇) | 文件系统和谐共处的基础

基本概念 | 官方定义 VFS&#xff08;Virtual File System&#xff09;是文件系统的虚拟层&#xff0c;它不是一个实际的文件系统&#xff0c;而是一个异构文件系统之上的软件粘合层&#xff0c;为用户提供统一的类Unix文件操作接口。由于不同类型的文件系统接口不统一&#x…

Flink HA模式下JobManager切换时发送告警

资源&版本信息 Flink版本1.14.6 运行平台&#xff1a;K8s HA使用ZK&#xff08;使用K8s的ETC应该是一个道理&#xff09; 详解Flink HA原理 Flink启动时会创建HighAvailabilityServices提供HA和相关基础服务&#xff0c;其中包括leaderRetrievalService和LeaderElecti…

搜索引擎的设计与实现(二)

目录 3 搜索引擎的基本原理 3.1搜索引擎的基本组成及其功能 l.搜索器 (Crawler) 2.索引器(Indexer) 3.检索器(Searcher) 4.用户接口(UserInterface) 3.2搜索引擎的详细工作流程 4 系统分析与设计 4.1系统分析 4.2系统概要设计 4.2系统实现目标 前面内容请移步 搜索引…

宁夏银川市起名专家的老师颜廷利:死神(死亡)并不可怕,可怕的是...

在中国优秀传统文化之中&#xff0c;汉语‘巳’字与‘四’同音&#xff0c;在阿拉伯数字里面&#xff0c;通常用‘4’来表示&#xff1b; 湖南长沙、四川成都、重庆、宁夏银川最靠谱最厉害的起名大师的老师颜廷利教授指出&#xff0c;作为汉语‘九’字&#xff0c;倘若是换一个…

[ACTF新生赛2020]SoulLike

没见过的错误&#xff1a; ida /ctg目录下的hexrays.cfg文件中的MAX_FUNCSIZE64 改为 MAX_FUNCSIZE1024 然后就是一堆数据 反正就是12个字符 from pwn import * flag"actf{" k0 for n in range(12):for i in range(33,127):pprocess("./SoulLike")_flag…

94.二叉树的中序遍历

刷算法题&#xff1a; 第一遍&#xff1a;1.看5分钟&#xff0c;没思路看题解 2.通过题解改进自己的解法&#xff0c;并且要写每行的注释以及自己的思路。 3.思考自己做到了题解的哪一步&#xff0c;下次怎么才能做对(总结方法) 4.整理到自己的自媒体平台。 5.再刷重复的类…

Python爬虫入门:网络世界的宝藏猎人

今天阿佑将带你踏上Python的肩膀&#xff0c;成为一名网络世界的宝藏猎人&#xff01; 文章目录 1. 引言1.1 简述Python在爬虫领域的地位1.2 阐明学习网络基础对爬虫的重要性 2. 背景介绍2.1 Python语言的流行与适用场景2.2 网络通信基础概念及其在数据抓取中的角色 3. Python基…

ssm+vue的公务用车管理智慧云服务监管平台查询统计(有报告)。Javaee项目,ssm vue前后端分离项目

演示视频&#xff1a; ssmvue的公务用车管理智慧云服务监管平台查询统计&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&…

求阶乘n!末尾0的个数溢出了怎么办

小林最近遇到一个问题&#xff1a;“对于任意给定的一个正整数n&#xff0c;统计其阶乘n&#xff01;的末尾中0的个数”&#xff0c;这个问题究竟该如何解决&#xff1f; 先用n5来解决这个问题。n的阶乘即n!5!5*4*3*2*1120&#xff0c;显然应该为2个数相乘等于10才能得到一个结…

量化交易包含些什么?

我们讲过许多关于量化交易的内容&#xff0c;但是量化交易具体可以做些什么&#xff1f;很多朋友都还不清楚&#xff0c;我们详细来探讨下&#xff01; 第一&#xff1a;什么是量化交易&#xff1f; 量化交易是一种利用先进的数学模型和计算机技术&#xff0c;从大量的历史数…

制造业精益生产KPI和智慧供应链管理方案和实践案例分享

随着工业4.0的推进和国家对制造业高质量发展的重视&#xff0c;工业数据已跃升为生产经营活动中不可或缺的核心要素&#xff0c;同时&#xff0c;工业数据也是形成新质生产力的优质生产要素&#xff0c;助力企业实现高效精益生产。 工业数据在制造业中的作用不可忽视&#xff…

Linux: 默认进程介绍

进程名称介绍systemdSystemd 可以管理所有系统资源。不同的资源统称为 Unit&#xff08;单位&#xff09;。 Unit 一共分成12种。 systemctl list-units命令可以查看当前系统的所有 Unitkthreaddkthreadd进程由idle通过kernel_thread创建&#xff0c;并始终运行在内核空间, 负责…

Hbase基础操作Demo(Java版)

一、前置条件 HBase服务&#xff1a;【快捷部署】023_HBase&#xff08;2.3.6&#xff09;开发环境&#xff1a;Java&#xff08;1.8&#xff09;、Maven&#xff08;3&#xff09;、IDE&#xff08;Idea 或 Eclipse&#xff09; 二、相关代码 代码结构如上图中①和② pom.x…

vue项目中使用websocke即时通讯实现系统公告实时获取并提醒

一、使用场景 发布者设置需要发布的公告内容、公告接收用户和发布时间&#xff0c;到达发布时间时及时通知提醒已登录系统用户&#xff0c;使用websocke来实现前端与服务器保持长连接&#xff0c;以便实时过去公告信息。 WebSocket是一种在单个TCP连接上进行全双工通信的协议…

draw.io 网页版二次开发(1):源码下载和环境搭建

目录 一 说明 二 源码地址以及下载 三 开发环境搭建 1. 前端工程地址 2. 配置开发环境 &#xff08;1&#xff09;安装 node.js &#xff08;2&#xff09;安装 serve 服务器 3. 运行 四 最后 一 说明 应公司项目要求&#xff0c;需要对draw.io进行二次开发&…

盛最多水的容器(双指针)

解题思路&#xff1a; 1&#xff0c;暴力解法&#xff08;超时&#xff09; 我们可以使用两层for循环进行遍历。找到那个最大的面积即可&#xff0c;这里我就不写代码了&#xff0c;因为写了也是超时。 2&#xff0c;双指针法 先定义两个指针一个在最左端&#xff0c;一个在…

C++ 派生类的引入与特性

一 继承与派生 从上面的例子可以看出&#xff1a; 继承&#xff1a;一旦指定了某种事物父代的本质特征&#xff0c;那么它的子代将会自动具有哪些性质。这就是一种朴素的可重用的概念。 派生&#xff1a;而且子代可以拥有父代没有的特性&#xff0c;这是可扩充的概念。 1 C 的…

Today At Apple 2024.04.15 Phone15 入门

官网&#xff1a; https://www.apple.com/today/Apple 亚洲第一大商店&#xff1a;Apple 静安零售店现已在上海开幕如下预约课程&#xff1a;下载 Apple Store&#xff08;不是app store&#xff09;&#xff0c;点击课程预约笔记&#xff1a;Today At Apple Notes果粉加群 &am…