feat: 添加两个图的割点算法实现

实现基于Tarjan算法的割点检测功能,分别用于解决P3388和P8436问题
This commit is contained in:
Zengtudor 2025-10-02 20:51:57 +08:00
parent 9a06eb0821
commit efab9f4d2e
2 changed files with 144 additions and 0 deletions

72
src/10/2/P3388.cpp Normal file
View File

@ -0,0 +1,72 @@
#include <algorithm>
#include <iostream>
#include <vector>
const int MAXN = 2e4 + 5;
int n, m;
std::vector<int> adj[MAXN];
int dfn[MAXN], low[MAXN], ts;
bool is_cut[MAXN];
std::vector<int> cut_points;
void tarjan(int u, int parent) {
dfn[u] = low[u] = ++ts;
int child_count = 0;
for (int v : adj[u]) {
if (v == parent) {
continue;
}
if (!dfn[v]) {
child_count++;
tarjan(v, u);
low[u] = std::min(low[u], low[v]);
if (parent != 0 && low[v] >= dfn[u]) {
is_cut[u] = true;
}
} else {
low[u] = std::min(low[u], dfn[v]);
}
}
if (parent == 0 && child_count > 1) {
is_cut[u] = true;
}
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> n >> m;
for (int i = 0; i < m; ++i) {
int u, v;
std::cin >> u >> v;
if (u == v) continue;
adj[u].push_back(v);
adj[v].push_back(u);
}
for (int i = 1; i <= n; ++i) {
if (!dfn[i]) {
tarjan(i, 0);
}
}
int count = 0;
for (int i = 1; i <= n; ++i) {
if (is_cut[i]) {
count++;
}
}
std::cout << count << "\n";
bool first = true;
for (int i = 1; i <= n; ++i) {
if (is_cut[i]) {
if (!first) {
std::cout << " ";
}
std::cout << i;
first = false;
}
}
std::cout << "\n";
}

72
src/10/2/P8436.cpp Normal file
View File

@ -0,0 +1,72 @@
#include <algorithm>
#include <iostream>
#include <vector>
const int MAXN = 2e4 + 5;
int n, m;
std::vector<int> adj[MAXN];
int dfn[MAXN], low[MAXN], ts;
bool is_cut[MAXN];
std::vector<int> cut_points;
void tarjan(int u, int parent) {
dfn[u] = low[u] = ++ts;
int child_count = 0;
for (int v : adj[u]) {
if (v == parent) {
continue;
}
if (!dfn[v]) {
child_count++;
tarjan(v, u);
low[u] = std::min(low[u], low[v]);
if (parent != 0 && low[v] >= dfn[u]) {
is_cut[u] = true;
}
} else {
low[u] = std::min(low[u], dfn[v]);
}
}
if (parent == 0 && child_count > 1) {
is_cut[u] = true;
}
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> n >> m;
for (int i = 0; i < m; ++i) {
int u, v;
std::cin >> u >> v;
if (u == v) continue;
adj[u].push_back(v);
adj[v].push_back(u);
}
for (int i = 1; i <= n; ++i) {
if (!dfn[i]) {
tarjan(i, 0);
}
}
int count = 0;
for (int i = 1; i <= n; ++i) {
if (is_cut[i]) {
count++;
}
}
std::cout << count << "\n";
bool first = true;
for (int i = 1; i <= n; ++i) {
if (is_cut[i]) {
if (!first) {
std::cout << " ";
}
std::cout << i;
first = false;
}
}
std::cout << "\n";
}//TODO REBUILD