update
This commit is contained in:
parent
30179dd5ea
commit
5e77358d92
3
src/11/P9869/P9869.cpp
Normal file
3
src/11/P9869/P9869.cpp
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
int main(){
|
||||||
|
|
||||||
|
}
|
81
src/11/P9869/P9869.md
Normal file
81
src/11/P9869/P9869.md
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
这个问题涉及三值逻辑(True、False、Unknown)变量的赋值与操作,需要找到一种初始赋值方案,使得在执行所有操作后,每个变量的最终值与初始值相同,并且使初始赋值中 `Unknown` 的变量尽可能少。
|
||||||
|
|
||||||
|
### 问题分析
|
||||||
|
|
||||||
|
1. **变量与操作**:
|
||||||
|
- 有 `n` 个变量,每个变量的值可以是 `T`、`F` 或 `U`。
|
||||||
|
- 有 `m` 条操作,这些操作包括直接赋值(如 `x_i ← T`)、赋值为另一个变量的值(如 `x_i ← x_j`)、或赋值为另一个变量的逻辑非(如 `x_i ← ¬x_j`)。
|
||||||
|
|
||||||
|
2. **目标**:
|
||||||
|
- 执行所有操作后,所有变量的最终值与初始值相同。
|
||||||
|
- 在满足上述条件的前提下,初始赋值中 `Unknown` 的变量数最少。
|
||||||
|
|
||||||
|
### 思路概述
|
||||||
|
|
||||||
|
为了满足最终值等于初始值,需要建立变量之间的依赖关系,并找出这些关系中的约束条件。可以将变量及其值的赋值关系看作是一个等式系统,通过这些等式来确定变量的可能取值。为了有效管理这些等式并高效求解,使用 **并查集(Union-Find** 是一种常见的方法。
|
||||||
|
|
||||||
|
### 具体步骤
|
||||||
|
|
||||||
|
1. **表示三值逻辑**:
|
||||||
|
- 将 `T`、`F`、`U` 分别映射为不同的整数值,便于在代码中处理:
|
||||||
|
- `T` 被表示为 `100001`
|
||||||
|
- `F` 被表示为 `-100001`
|
||||||
|
- `U` 被表示为 `0`
|
||||||
|
|
||||||
|
2. **并查集初始化**:
|
||||||
|
- 使用一个数组 `fa` 来表示每个变量的父节点或代表元素。初始时,每个变量的父节点指向自己。
|
||||||
|
|
||||||
|
3. **处理每条操作**:
|
||||||
|
- **直接赋值操作**(`T`、`F`、`U`):
|
||||||
|
- 如果操作是 `x_i ← T`,则将 `fa[x_i]` 设为 `T` 的表示值。
|
||||||
|
- 类似地处理 `x_i ← F` 和 `x_i ← U`。
|
||||||
|
- **赋值为另一个变量的值**(`+` 操作):
|
||||||
|
- 如果操作是 `x_i ← x_j`,则将 `fa[x_i]` 设为 `fa[x_j]`,表示 `x_i` 与 `x_j` 的值相同。
|
||||||
|
- **赋值为另一个变量的非值**(`-` 操作):
|
||||||
|
- 如果操作是 `x_i ← ¬x_j`,则将 `fa[x_i]` 设为 `-fa[x_j]`,表示 `x_i` 是 `x_j` 值的逻辑非。
|
||||||
|
|
||||||
|
4. **查找变量的最终值**:
|
||||||
|
- 使用 `find` 函数来查找变量的代表值。
|
||||||
|
- 在 `find` 函数中:
|
||||||
|
- 对于 `T` 和 `F`,直接返回其表示值。
|
||||||
|
- 对于 `U`,返回 `0`。
|
||||||
|
- 对于其他情况,通过递归查找父节点,处理逻辑非的情况,并使用 `book` 数组避免死循环。
|
||||||
|
|
||||||
|
5. **计算 `Unknown` 的最小数量**:
|
||||||
|
- 遍历所有变量,使用 `find` 函数确定每个变量的最终值。
|
||||||
|
- 如果某个变量的最终值为 `U`,则计数。
|
||||||
|
- 输出所有测试数据中 `Unknown` 变量的最小数量。
|
||||||
|
|
||||||
|
### 关键细节与优化
|
||||||
|
|
||||||
|
- **处理逻辑非(`¬`)**:
|
||||||
|
- 逻辑非会改变变量的值,因此在并查集中需要表示变量与其非值的关系。
|
||||||
|
- 使用负值表示逻辑非关系,例如 `x_i ← ¬x_j` 表示 `fa[x_i] = -fa[x_j]`。
|
||||||
|
|
||||||
|
- **防止死循环**:
|
||||||
|
- 当变量的代表值可能因逻辑非关系而相互指向时,可能会引发无限递归。通过 `book` 数组记录已经访问过的节点,从而避免死循环。
|
||||||
|
|
||||||
|
- **高效的查找操作**:
|
||||||
|
- 使用路径压缩技术优化 `find` 函数,使得查找操作的时间复杂度接近常数时间,确保算法在大规模数据(`n, m ≤ 10^5`)下依然高效。
|
||||||
|
|
||||||
|
### 示例解析
|
||||||
|
|
||||||
|
以第一个样例为例:
|
||||||
|
|
||||||
|
```
|
||||||
|
3 3
|
||||||
|
- 2 1
|
||||||
|
- 3 2
|
||||||
|
+ 1 3
|
||||||
|
```
|
||||||
|
|
||||||
|
- 操作步骤:
|
||||||
|
1. `x_2 ← ¬x_1`:`fa[2] = -fa[1]`
|
||||||
|
2. `x_3 ← ¬x_2`:`fa[3] = -fa[2]`
|
||||||
|
3. `x_1 ← x_3`:`fa[1] = fa[3]`
|
||||||
|
|
||||||
|
- 通过并查集的合并与查找,最终确定每个变量的值,使得初始值与最终值相同,并且 `Unknown` 的数量最少。在该示例中,可以赋予 `x1 = T`,`x2 = F`,`x3 = T`,使得 `Unknown` 的数量为 `0`。
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
该解决方案通过并查集有效地管理变量之间的赋值与逻辑关系,处理了直接赋值、变量赋值以及逻辑非赋值的情况。通过高效的查找与合并操作,能够在大规模数据下快速求解,同时通过合理的表示与优化,确保了算法的正确性与效率。
|
Loading…
Reference in New Issue
Block a user