【算法/图论】2-SAT问题详解

这篇具有很好参考价值的文章主要介绍了【算法/图论】2-SAT问题详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、问题引入

在了解2-SAT的定义之前,我们需要给出一些基础定义。

布尔变量(Boolean variable):只能取 1 1 1(true)或 0 0 0(false)的变量。

否定连接词 ¬ \neg ¬(negation):取布尔变量的否定。例如 ¬ 1 = 0 \neg1=0 ¬1=0 ¬ 0 = 1 \neg0=1 ¬0=1 ¬ ( ¬ a ) = a \neg(\neg a)=a ¬(¬a)=a

合取连接词 ∧ \land (conjunction):表示“且”。 a ∧ b = 1 a\land b=1 ab=1当且仅当 a , b a,b a,b同时为 1 1 1

析取连接词 ∨ \lor (disjunction):表示“或”。 a ∨ b = 1 a\lor b=1 ab=1当且仅当 a , b a,b a,b之中至少有一个为 1 1 1

蕴含连接词 → \to (implication): a → b a\to b ab等价于 ¬ a ∨ b \neg a\lor b ¬ab a → b = 1 a\to b=1 ab=1当且仅当 a = 0 a=0 a=0 b = 1 b=1 b=1。换言之,若 a = 1 a=1 a=1,则必有 b = 1 b=1 b=1,否则蕴含关系不成立;若 a = 0 a=0 a=0,则不论 b b b取何值,蕴含关系都成立。

文字(literal):变量 x x x及其否定 ¬ x \neg x ¬x称为文字。

子句/简单析取式(clause):若干个文字由析取连接词连接起来形成的布尔表达式称为简单析取式。例如 a ∨ b ∨ ¬ c a\lor b\lor\neg c ab¬c ¬ d ∨ d ∨ e ∨ ¬ f \neg d\lor d\lor e\lor\neg f ¬dde¬f

合取范式(CNF,Conjunctive Normal Form):若干个简单析取式由合取连接词连接起来形成的布尔表达式称为合取范式(即“简单析取式的合取”)。例如 ( p ∨ ¬ q ) ∧ ( ¬ p ∨ r ∨ s ) ∧ ¬ r ∧ ( s ∨ ¬ s ) (p\lor \neg q)\land(\neg p\lor r\lor s)\land \neg r\land(s\lor\neg s) (p¬q)(¬prs)¬r(s¬s),它有四个子句。

2-CNF:每个子句仅包含两个文字的合取范式。例如 ( a ∨ ¬ b ) ∧ ( b ∨ c ) ∧ ( c ∨ ¬ f ) ∨ ( ¬ d ∨ e ) (a\lor\neg b)\land(b\lor c)\land(c\lor\neg f)\lor(\neg d\lor e) (a¬b)(bc)(c¬f)(¬de)

布尔表达式的可满足性:对于一个布尔表达式,如果存在各变量的一组赋值,使得该表达式的值为 1 1 1,则称该表达式是可满足的。对于合取范式,因为各子句之间是且的关系,所以要使它取值为 1 1 1就必须使各子句取值都为 1 1 1。对于上面给出的式子 ( a ∨ ¬ b ) ∧ ( b ∨ c ) ∧ ( c ∨ ¬ f ) ∨ ( ¬ d ∨ e ) (a\lor\neg b)\land(b\lor c)\land(c\lor\neg f)\lor(\neg d\lor e) (a¬b)(bc)(c¬f)(¬de),令 a = 1 , b = 1 , c = 1 , d = 0 , e = 0 , f = 1 a=1,b=1,c=1,d=0,e=0,f=1 a=1,b=1,c=1,d=0,e=0,f=1可以使其取值为 1 1 1,所以它是可满足的;但对于式子 ( a ∨ ¬ b ) ∧ ( b ∨ c ) ∧ ( b ∨ ¬ c ) ∧ ( ¬ a ∨ ¬ b ) (a\lor\neg b)\land(b\lor c)\land(b\lor\neg c)\land(\neg a\lor\neg b) (a¬b)(bc)(b¬c)(¬a¬b),不论 a , b , c a,b,c a,b,c取何值,式子的值都是 0 0 0,因此它是不可满足的。

2-SAT:也称2-CNF-SAT,是判断2-CNF是否可满足的问题。(判断一般的合取范式是否可满足的问题是 N P \mathsf{NP} NP完全问题,至今没有发现多项式时间的算法;但2-SAT是一个特例,具有高效算法。)

二、问题求解

1. 转化为蕴含关系

考虑2-CNF的一个子句 ( a ∨ ¬ b ) (a\lor\neg b) (a¬b),要让这个子句满足,就是让 ( a ∨ ¬ b ) = 1 (a\lor\neg b)=1 (a¬b)=1。现在令 a = 0 a=0 a=0,那么 ¬ b \neg b ¬b一定等于 1 1 1,因为如果 ¬ b \neg b ¬b也等于 0 0 0,那么 a a a ¬ b \neg b ¬b同时为 0 0 0,该子句的取值就是 0 0 0了;同理,若 ¬ b = 0 \neg b=0 ¬b=0,则可以知道 a a a一定是 1 1 1。换言之: ¬ a \neg a ¬a a = 0 a=0 a=0可以推出 ¬ b \neg b ¬b,而 b b b ¬ b = 0 \neg b=0 ¬b=0,即 ¬ ( ¬ b ) = b = 1 \neg(\neg b)=b=1 ¬(¬b)=b=1可以推出 a a a。所以, ( a ∨ ¬ b ) (a\lor\neg b) (a¬b)就等价于 ( ¬ a → ¬ b ) ∧ ( b → a ) (\neg a\to\neg b)\land(b\to a) (¬a¬b)(ba)。一般地,设 p , q p,q p,q是两个文字,则子句 ( p ∨ q ) (p\lor q) (pq)等价于两个蕴含关系 ¬ p → q \neg p\to q ¬pq ¬ q → p \neg q\to p ¬qp p = a p=a p=a,则 ¬ p = ¬ a \neg p=\neg a ¬p=¬a;若 p = ¬ a p=\neg a p=¬a,则 ¬ p = ¬ ( ¬ a ) = a \neg p=\neg(\neg a)=a ¬p=¬(¬a)=a

具体地说,我们获得蕴含关系方式由下表给出:

子句 蕴含关系
a ∨ b a\lor b ab ¬ a → b \neg a\to b ¬ab ¬ b → a \neg b\to a ¬ba
a ∨ ¬ b a\lor\neg b a¬b ¬ a → ¬ b \neg a\to\neg b ¬a¬b b → a b\to a ba
¬ a ∨ b \neg a\lor b ¬ab a → b a\to b ab ¬ b → ¬ a \neg b\to\neg a ¬b¬a
¬ a ∨ ¬ b \neg a\lor\neg b ¬a¬b a → ¬ b a\to\neg b a¬b b → ¬ a b\to\neg a b¬a

2. 建图

我们把每个子句表示成蕴含关系后,就可以根据蕴含关系建图。假设有 n n n个布尔变量,那么图有 2 n 2n 2n个节点,每个变量及其否定各有一个节点(比如变量 a a a对应两个节点: a a a ¬ a \neg a ¬a)。根据蕴含关系连边,若有 ¬ a → ¬ b \neg a\to\neg b ¬a¬b就从 ¬ a \neg a ¬a ¬ b \neg b ¬b连一条边;若有 b → a b\to a ba就从 b b b a a a连一条边。注意,每个子句连 2 2 2条边:若 p p p q q q有一条边,那么 ¬ q \neg q ¬q ¬ p \neg p ¬p也有一条边(可以通过逆否命题和原命题等价来理解)。

3. 判断可满足性

我们说“ a → b a\to b ab”,指的是若 a = 1 a=1 a=1,那么 b b b一定等于 1 1 1;若 a ≠ 1 a\ne1 a=1,那么 b b b等于什么都可以。蕴含关系有传递性,例如 a → b a\to b ab b → c b\to c bc就有 a → c a\to c ac。若图中有从 a a a b b b的一条路径,那么就有 a → b a\to b ab。若 a a a b b b处于同一个强连通分量中,即 a a a b b b有路径、 b b b a a a有路径,那么就有 a → b a\to b ab b → a b\to a ba,此时,若 a = 1 a=1 a=1,则 b = 1 b=1 b=1;若 b = 1 b=1 b=1,则 a = 1 a=1 a=1;若 a = 0 a=0 a=0,则 b = 0 b=0 b=0,因为如果 b = 1 b=1 b=1的话就有 a = 1 a=1 a=1了。于是我们得出结论:若 a a a b b b处于同一个强连通分量中,则有 a → b ∧ b → a a\to b\land b\to a abba,此时 a a a b b b取值必须相同。

什么时候不可满足呢?就是出现矛盾的时候。所谓矛盾,就是存在变量 x x x,使得 x x x ¬ x \neg x ¬x相等。换言之,如果某个变量和其否定出现在了同一个强连通分量中,那么这个式子就是不可满足的。如果没有这种情况,就是可满足的。

详细地说,如果 x x x ¬ x \neg x ¬x在同一个强连通分量中,那么我们有 x → ¬ x x\to\neg x x¬x ¬ x → x \neg x\to x ¬xx。如果 x = 1 x=1 x=1,那么由 x → ¬ x x\to\neg x x¬x ¬ x = 1 \neg x=1 ¬x=1,即 x = 0 x=0 x=0,但是一个变量不能同时取 1 1 1 0 0 0,所以不成立;如果 x = 0 x=0 x=0,那么 ¬ x = 1 \neg x=1 ¬x=1,由 ¬ x → x \neg x\to x ¬xx x = 1 x=1 x=1,同样出现了矛盾。反之,如果没有一个变量,使得它本身和它的否定在同一个强连通分量中,那么我们总能构造出一个可满足赋值,这就是下一段讨论的内容。因此,“某一个变量的本身和否定在同一个强连通分量中”是输入的2-CNF不可满足的充要条件。

4. 赋值

当我们知道某个式子是可满足的时候,我们希望找到使其值为 1 1 1的一组变量的赋值。此时对于变量 x x x x x x ¬ x \neg x ¬x一定不属于同一个强连通分量。要求出强连通分量,就需要对原图进行缩点,顺便可以求出得到的有向无环图的拓扑序。令 x x x所在强连通分量的拓扑序为 t x t_x tx。我们这样进行赋值:

  • t x < t ¬ x t_x<t_{\neg x} tx<t¬x,则令 x = 0 x=0 x=0
  • t x > t ¬ x t_x>t_{\neg x} tx>t¬x,则令 x = 1 x=1 x=1

t x = t ¬ x t_x=t_{\neg x} tx=t¬x的情况是不存在的,因为 x x x ¬ x \neg x ¬x不在同一个强连通分量中。

如果有从 x x x ¬ x \neg x ¬x或从 ¬ x \neg x ¬x x x x的路径,那么这个很好理解。

  • t x < t ¬ x t_x<t_{\neg x} tx<t¬x就是说有从 x x x ¬ x \neg x ¬x的路径,这种情况下我们有 x → ¬ x x\to\neg x x¬x,只有当 x = 0 x=0 x=0的时候才可满足。
  • t x > t ¬ x t_x>t_{\neg x} tx>t¬x就是说有从 ¬ x \neg x ¬x x x x的路径,这种情况下我们有 ¬ x → x \neg x\to x ¬xx,只有当 x = 1 x=1 x=1的时候才可满足。

下面我们来证明这种赋值办法不会违反任何蕴含关系。

  • 首先,它不会违反 x x x ¬ x \neg x ¬x之间的蕴含关系,因为 x x x ¬ x \neg x ¬x属于不同的强连通分量,二者之间最多只能有一个蕴含关系,而我们赋值的方法总能满足这个蕴含关系。
  • 其次,我们考虑变量 x x x和另一个变量 y y y的蕴含关系。我们假设有 x → y x\to y xy(如果有 ¬ x → y \neg x\to y ¬xy x → ¬ y x\to\neg y x¬y ¬ x → ¬ y \neg x\to\neg y ¬x¬y同理)。我们担心的情况是: x = 1 x=1 x=1 y = 0 y=0 y=0,这样蕴含关系就被违反了。下面我们用反证法证明这种情况不存在。假设 x = 1 x=1 x=1 y = 0 y=0 y=0 x → y x\to y xy三个条件,那么我们可以得出以下结论:
    • x = 1 x=1 x=1知道 t ¬ x < t x t_{\neg x}<t_x t¬x<tx(见两个赋值规则);
    • y = 0 y=0 y=0知道 t y < t ¬ y t_y<t_{\neg y} ty<t¬y
    • x → y x\to y xy知道 t x ≤ t y t_x\le t_y txty。(如果 x x x y y y在同一个强连通分量里,则 t x = t y t_x=t_y tx=ty;如果在不同的强连通分量里,那么我们有从 x x x y y y的一条边,因此 x x x y y y先被访问。至于为什么如果有 x x x y y y的边那么 x x x y y y先被访问,这是拓扑排序的定义。)
  • 综合这三个不等式,我们得到 t ¬ x < t x ≤ t y < t ¬ y t_{\neg x}<t_x\le t_y<t_{\neg y} t¬x<txty<t¬y。但是,我们知道原命题等价于逆否命题,也就是说, x → y x\to y xy成立意味着 ¬ y → ¬ x \neg y\to\neg x ¬y¬x也一定成立,这表明 t ¬ y ≤ t ¬ x t_{\neg y}\le t_{\neg x} t¬yt¬x,与绿色不等式矛盾。因此假设不成立,违反 x → y x\to y xy的情况不存在,换言之,所有蕴含关系都被满足了,这意味着输入的2-CNF公式被满足了。综上所述,我们的赋值策略是正确的。

三、两个例子

第一个例子

给定的2-CNF表达式为 ( a ∨ ¬ b ) ∧ ( ¬ a ∨ b ) ∧ ( b ∨ ¬ c ) ∧ ( a ∨ c ) (a\lor\neg b)\land(\neg a\lor b)\land(b\lor\neg c)\land(a\lor c) (a¬b)(¬ab)(b¬c)(ac)

2-sat 问题,OI,数据结构与算法,计算理论,算法,图论,数学,学习,经验分享

图包含四个强连通分量: { a , b } , { c } , { ¬ a , ¬ b } , { ¬ c } \{a,b\},\{c\},\{\neg a,\neg b\},\{\neg c\} {a,b},{c},{¬a,¬b},{¬c}。没有出现某个变量及其否定在同一个强连通分量的情况,所以是可满足的。进行缩点:

2-sat 问题,OI,数据结构与算法,计算理论,算法,图论,数学,学习,经验分享

拓扑序为 t ¬ a , ¬ b < t c < t ¬ c < t a , b t_{\neg a,\neg b}<t_c<t_{\neg c}<t_{a,b} t¬a,¬b<tc<t¬c<ta,b。因为 t ¬ a < t a t_{\neg a}<t_a t¬a<ta,所以 a = 1 a=1 a=1。同理 b = 1 b=1 b=1。因为 t c < t ¬ c t_c<t_{\neg c} tc<t¬c,所以 c = 0 c=0 c=0

a = 1 , b = 1 , c = 0 a=1,b=1,c=0 a=1,b=1,c=0代入2-CNF中验算可得其值为 1 1 1

第二个例子

给定的2-CNF表达式为 ( a ∨ ¬ b ) ∧ ( b ∨ c ) ∧ ( b ∨ ¬ c ) ∧ ( ¬ a ∨ ¬ b ) (a\lor\neg b)\land(b\lor c)\land(b\lor\neg c)\land(\neg a\lor\neg b) (a¬b)(bc)(b¬c)(¬a¬b)

2-sat 问题,OI,数据结构与算法,计算理论,算法,图论,数学,学习,经验分享

所有节点都在同一个强连通分量中,所以这个式子不可满足。

四、基于Tarjan算法的代码实现

详细思路

设有 n n n个变量, m m m个子句,则有 2 n 2n 2n个节点。编号 i i i 1 ≤ i ≤ n 1\le i\le n 1in)的节点对应变量 x i x_i xi i + n i+n i+n对应 ¬ x i \neg x_i ¬xi。根据每个子句建图,图中共 2 m 2m 2m条边。使用Tarjan算法进行缩点,co数组存储每个节点的染色,实际上就是有向无环图的逆拓扑序(因为在DFS树中越深的节点越先被染色)。对于每个变量 x i x_i xi,考察节点 i i i和节点 i + n i+n i+n的染色是否相同,若相同说明 x i x_i xi ¬ x i \neg x_i ¬xi在同一个强连通分量,出现矛盾。而后根据拓扑序进行赋值:若 i i i的拓扑序小于 i + n i+n i+n,对应co[i] > co[i + n] x i = 0 x_i=0 xi=0;反之 x i = 1 x_i=1 xi=1。可以简写为 x i = x_i= xi=co[i] < co[i + n]

洛谷P4782 【模板】2-SAT 问题

题目描述

n n n 个布尔变量 x 1 x_1 x1~ x n x_n xn,另有 m m m 个需要满足的条件,每个条件的形式都是 「 x i x_i xitrue / false x j x_j xjtrue / false」。比如 「 x 1 x_1 x1 为真或 x 3 x_3 x3 为假」、「 x 7 x_7 x7 为假或 x 2 x_2 x2 为假」。

2-SAT 问题的目标是给每个变量赋值使得所有条件得到满足。

输入格式

第一行两个整数 n n n m m m,意义如题面所述。

接下来 m m m 行每行 4 4 4 个整数 i i i, a a a, j j j, b b b,表示 「 x i x_i xi a a a x j x_j xj b b b」( a , b ∈ { 0 , 1 } a, b\in \{0,1\} a,b{0,1})

输出格式

如无解,输出 IMPOSSIBLE;否则输出 POSSIBLE

下一行 n n n 个整数 x 1 x_1 x1~ x n x_n xn x i ∈ { 0 , 1 } x_i\in\{0,1\} xi{0,1}),表示构造出的解。

样例 #1

样例输入 #1
3 1
1 1 3 0
样例输出 #1
POSSIBLE
0 0 0

提示

1 ≤ n , m ≤ 1 0 6 1\leq n, m\leq 10^6 1n,m106 , 前 3 3 3 个点卡小错误,后面 5 5 5 个点卡效率。

由于数据随机生成,可能会含有(10 0 10 0)之类的坑,但按照最常规写法的写的标程没有出错,各个数据点卡什么的提示在标程里

分析

我们需要把条件“ x i x_i xi a a a x j x_j xj b b b”转化为子句。其实 a = 0 a=0 a=0表示子句中 x i x_i xi前面有否定连接词, b = 0 b=0 b=0表示子句中 x j x_j xj前面有否定连接词。转换关系如下:

a a a b b b 子句 第一个蕴含关系 第二个蕴含关系
1 1 1 1 1 1 x i ∨ x j x_i\lor x_j xixj ¬ x i → x j \neg x_i\to x_j ¬xixj ¬ x j → x i \neg x_j\to x_i ¬xjxi
1 1 1 0 0 0 x i ∨ ¬ x j x_i\lor\neg x_j xi¬xj ¬ x i → ¬ x j \neg x_i\to\neg x_j ¬xi¬xj x j → x i x_j\to x_i xjxi
0 0 0 1 1 1 ¬ x i ∨ x j \neg x_i\lor x_j ¬xixj x i → x j x_i\to x_j xixj ¬ x j → ¬ x i \neg x_j\to\neg x_i ¬xj¬xi
0 0 0 0 0 0 ¬ x i ∨ ¬ x j \neg x_i\lor\neg x_j ¬xi¬xj x i → ¬ x j x_i\to\neg x_j xi¬xj x j → ¬ x i x_j\to\neg x_i xj¬xi

因为 ¬ y \neg y ¬y在图中对应的节点编号为 y y y的编号加 n n n,所以加入第一个蕴含关系时我们判断 a a a是否为 1 1 1,若为 1 1 1则给 x i x_i xi的编号加 n n n变成 ¬ x i \neg x_i ¬xi;若 b b b 0 0 0则给 x j x_j xj的编号加 n n n变成 ¬ x j \neg x_j ¬xj。加入第二个蕴含关系时,若 b = 1 b=1 b=1 x j x_j xj n n n,若 a = 0 a=0 a=0 x i x_i xi n n n文章来源地址https://www.toymoban.com/news/detail-784236.html

代码实现

#include <iostream>
#include <cstdio>
#include <stack>

using namespace std;

const int MAXN = 2e6 + 5, MAXM = 2e6 + 5;

int n, m, tot, nxt[MAXM], first[MAXN], go[MAXM],
    dfn[MAXN], low[MAXN], co[MAXN], col; 
// n为变量个数,m为条件(子句)个数,nxt、first、go是链式前向星用到的数组,
// dfn为Tarjan算法的DFS序数组,low为Tarjan算法的low数组,
// co是颜色(即节点的强连通分量编号),col为强连通分量个数
stack<int> stk;

inline void add_edge(int u, int v) // 加边
{
    nxt[++tot] = first[u];
    first[u] = tot;
    go[tot] = v;
}

void Tarjan(int u) // Tarjan算法求强连通分量
{
    low[u] = dfn[u] = ++tot;
    stk.push(u);
    for(int e = first[u]; e; e = nxt[e])
    {
        int v = go[e];
        if(!dfn[v])
        {
            Tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(!co[v])
        {
            low[u] = min(low[u], low[v]);
        }
    }
    if(low[u] == dfn[u])
    {
        co[u] = ++col;
        while(stk.top() != u)
            co[stk.top()] = col, stk.pop();
        stk.pop();
    }
}

int main()
{
    cin >> n >> m;
    for(int t = 1; t <= m; ++t) // 连边
    {
        int i, a, j, b;
        cin >> i >> a >> j >> b;
        int u = i;
        if(a) u += n;
        int v = j;
        if(!b) v += n;
        add_edge(u, v);
        u = j;
        if(b) u += n;
        v = i;
        if(!a) v += n;
        add_edge(u, v);
    }
    for(int i = 1; i <= 2 * n; ++i)
        if(!dfn[i]) Tarjan(i); // Tarjan缩点
    for(int i = 1; i <= n; ++i)
        if(co[i] == co[i + n]) // 判断冲突
        {
            puts("IMPOSSIBLE");
            return 0;
        }
    puts("POSSIBLE");
    for(int i = 1; i <= n; ++i) // 赋值
        cout << (co[i] < co[i + n]) << ' ';
    cout << endl;
    return 0;
}

到了这里,关于【算法/图论】2-SAT问题详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Sat-Hacking(3):Starlink终端逆向分析

    Starlink终端是SpaceX推出的卫星互联网终端设备,它的目的是为了提供高速、低延迟的卫星互联网服务。该终端设备采用了一种平板天线设计,可以自动搜索、跟踪并连接卫星信号,同时还具有数据处理、无线网络传输等多种功能。在 Starlink 卫星互联网系统中,用户设备端采用

    2024年02月15日
    浏览(69)
  • Sat-Hacking(2):Starlink卫星通信频段

    了解卫星通信频段是学习卫星安全的基础理论知识,卫星通信频段是指用于卫星通信的无线电波频谱范围。在卫星通信中,无线电波在地面站与卫星之间传输信息,实现通信和数据传输。为了使各种卫星和地面系统之间的通信有效且互不干扰,国际电信联盟(ITU)将频谱划分

    2024年02月06日
    浏览(37)
  • 「SAP ABAP」OPEN SQL(九)【SAT事务码】

    💂 作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后端的开发语言ABAP,SQL进行任务的完成,对SAP企业管理系统,SAP ABAP开发和数据库具有较

    2023年04月13日
    浏览(46)
  • Sat-Hacking(4):Starlink路由器逆向分析-上篇

    在本篇文章中,我们将探讨 SpaceX Starlink 路由器的逆向分析过程。Starlink 是 SpaceX 推出的一项革命性的卫星互联网服务,旨在为全球偏远地区提供高速、低延迟的互联网连接。为了实现这一目标,Starlink 需要一个高性能的路由器来管理用户的互联网连接。逆向分析这种设备对于

    2024年02月10日
    浏览(51)
  • 有趣的Hack-A-Sat黑掉卫星挑战赛——跟踪卫星

    国家太空安全是国家安全在空间领域的表现。随着太空技术在政治、经济、军事、文化等各个领域的应用不断增加,太空已经成为国家赖以生存与发展的命脉之一,凝聚着巨大的国家利益,太空安全的重要性日益凸显[1]。而在信息化时代,太空安全与信息安全紧密地结合在一

    2024年02月12日
    浏览(106)
  • 有趣的Hack-A-Sat黑掉卫星挑战赛——被破坏的阿波罗计算机(解法二)

    国家太空安全是国家安全在空间领域的表现。随着太空技术在政治、经济、军事、文化等各个领域的应用不断增加,太空已经成为国家赖以生存与发展的命脉之一,凝聚着巨大的国家利益,太空安全的重要性日益凸显[1]。而在信息化时代,太空安全与信息安全紧密地结合在一

    2023年04月22日
    浏览(50)
  • 【数据结构与算法】图论及其相关算法

    线性表局限于一个直接前驱和一个直接后继的关系,树也只能有一个直接前驱也就是父节点,当我们需要表示多对多的关系时, 这里我们就用到了图。 图是一种数据结构,其中结点可以具有零个或多个相邻元素。两个结点之间的连接称为边。 结点也可以称为顶点。如图:

    2024年02月09日
    浏览(38)
  • 【数据结构】长篇详解堆,堆的向上/向下调整算法,堆排序及TopK问题

    堆就是将一组数据所有元素按完全二叉树的顺序存储方式存储在一个 一维数组 中,并满足树中 每一个父亲节点都要大于其子节点 称为 大堆 (树中 每一个父亲节点都要大于其子节点 称为 小堆 )。 性质 ①对于大堆(大根堆)来说,堆的顶部也就是数组首元素一定是最大的元素 ②

    2024年02月07日
    浏览(40)
  • 数据结构的应用场景:如社交网络、路由算法、图论、网络协议等

    作者:禅与计算机程序设计艺术 数据结构(Data Structure)是计算机科学中存储、组织、管理数据的方式,主要用于解决信息检索、处理和运算时的效率及空间占用问题。它是指数据元素(elements)之间的关系、顺序和逻辑结构,以及相互作用的算法。数据结构通常采用抽象数据类

    2024年02月14日
    浏览(46)
  • 数据结构KMP算法详解

    目录 1. KMP算法是什么? 2. KMP算法的由来 2.1 需要要解决的问题 2.2 一开始想到的方法 2.3 KMP算法诞生了 3.KMP算法的详解 4.KMP算法的实现 5.KMP算法的改进 KMP算法是一种改进的字符串匹配算法,即可以 快速的从主串中找到子串的算法 ,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人

    2024年02月12日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包