NewCodeTemplate

This commit is contained in:
e2hang
2025-12-16 20:36:27 +08:00
parent 684e35b210
commit 8253f2dcbc
26 changed files with 2547 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
#include <iostream>
#include <vector>
using namespace std;
/*
* Floyd-Warshall 传递闭包Transitive Closure
* ----------------------------------------------
* 用途:求有向图中任意两点 i -> j 是否可达。
*
* 核心思想:
* 如果 i 能到达 k 且 k 能到达 j
* 则 i 也能到达 j
*
* reach[i][j] = reach[i][j] || (reach[i][k] && reach[k][j])
*
* 输入:
* n节点数量默认节点编号为 0~n-1
* m边数量
* 若干有向边 u -> v
*
* 结果:
* reach[i][j] = true 表示可达
*/
int main() {
int n, m;
cin >> n >> m;
// reach[i][j] 表示 i 是否能到 j
vector<vector<bool>> reach(n, vector<bool>(n, false));
// 自身可达
for (int i = 0; i < n; i++) {
reach[i][i] = true;
}
// 输入边
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
reach[u][v] = true;
}
/*
* Floyd 传递闭包核心循环
* i -> k -> j 中的 k 作为中间点
*
* 需要确保三重循环的顺序为:
* for(k)
* for(i)
* for(j)
*
* 必须这么写,因为:
* - k 作为阶段性“允许使用的中间点”
* - 在第 k 轮,只能使用编号 ≤ k 的中间节点
*/
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
// 如果 i → k 不可达,则无须检查 j
if (!reach[i][k]) continue;
for (int j = 0; j < n; j++) {
// 如果 k → j 可达,则 i → j 也可达
if (reach[k][j]) {
reach[i][j] = true;
}
}
}
}
// 输出可达矩阵(可选)
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << reach[i][j] << (j + 1 == n ? '\n' : ' ');
}
}
return 0;
}