Skip to content

Commit

Permalink
2024.10.20 [PATCH] v1.8.7 热更新:
Browse files Browse the repository at this point in the history
《图论→缩点(Tarjan 算法)→(无向图)割边缩点》重构
  • Loading branch information
hh2048 authored Oct 21, 2024
1 parent 438e310 commit 98d9edf
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 24 deletions.
52 changes: 28 additions & 24 deletions 02 - 打印稿模板汇总/03A - 图论.md
Original file line number Diff line number Diff line change
Expand Up @@ -431,31 +431,31 @@ struct SCC {
```c++
struct EDCC {
int n, now, cnt;
vector<vector<int>> ver;
int n, m, now, cnt;
vector<vector<array<int, 2>>> ver;
vector<int> dfn, low, col, S;
set<array<int, 2>> bridge;
set<array<int, 2>> bridge, direct; // 如果不需要,删除这一部分可以得到一些时间上的优化

EDCC(int n) : n(n), ver(n + 1), low(n + 1) {
dfn.resize(n + 1, -1);
col.resize(n + 1, -1);
now = cnt = 0;
EDCC(int n) : n(n), low(n + 1), ver(n + 1), dfn(n + 1), col(n + 1) {
m = now = cnt = 0;
}
void add(int x, int y) { // 和 scc 相比多了一条连边
ver[x].push_back(y);
ver[y].push_back(x);
ver[x].push_back({y, m});
ver[y].push_back({x, m++});
}
void tarjan(int x, int fa) { // 和 scc 相比多了一个 fa
dfn[x] = low[x] = now++;
void tarjan(int x, int fa) {
dfn[x] = low[x] = ++now;
S.push_back(x);
for (auto y : ver[x]) {
if (y == fa) continue;
if (dfn[y] == -1) {
bridge.insert({x, y}); // 储存割边
tarjan(y, x);
for (auto &[y, id] : ver[x]) {
if (!dfn[y]) {
direct.insert({x, y});
tarjan(y, id);
low[x] = min(low[x], low[y]);
} else if (col[y] == -1 && dfn[y] < dfn[x]) {
bridge.insert({x, y});
if (dfn[x] < low[y]) {
bridge.insert({x, y});
}
} else if (id != fa && dfn[y] < dfn[x]) {
direct.insert({x, y});
low[x] = min(low[x], dfn[y]);
}
}
Expand All @@ -469,18 +469,22 @@ struct EDCC {
} while (pre != x);
}
}
auto work() { // [cnt 新图的顶点数量, bridge 全部割边]
auto work() {
for (int i = 1; i <= n; i++) { // 避免图不连通
if (dfn[i] == -1) {
if (!dfn[i]) {
tarjan(i, 0);
}
}

vector<int> siz(cnt + 1); // siz 每个边双中点的数量
vector<vector<int>> adj(cnt + 1); // adj 新图
/**
* @param cnt 新图的顶点数量, adj 新图, col 旧图节点对应的新图节点
* @param siz 旧图每一个边双中点的数量
* @param bridge 全部割边, direct 非割边定向
*/
vector<int> siz(cnt + 1);
vector<vector<int>> adj(cnt + 1);
for (int i = 1; i <= n; i++) {
siz[col[i]]++;
for (auto j : ver[i]) {
for (auto &[j, id] : ver[i]) {
int x = col[i], y = col[j];
if (x != y) {
adj[x].push_back(y);
Expand Down
4 changes: 4 additions & 0 deletions 02 - 打印稿模板汇总/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

### 8.7(2024.10.07封包)

2024.10.20 [PATCH]

- **重要更新**:《图论→缩点(Tarjan 算法)→(无向图)割边缩点》重构。

2024.10.07

- **重要更新**:《图论→二分图最大匹配→HopcroftKarp算法(基于最大流)解》重构,此前的版本可能被卡(时间与正确性均)。
Expand Down

0 comments on commit 98d9edf

Please sign in to comment.