Files
python/TangDou/AcWing/DCC/T103489.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

72 lines
2.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
//此题是P8436的弱化版本,弱化了记录每个边双中点有哪些:vector<int> belong[N];
const int N = 500010, M = 2000010 * 2;
int n, m;
int dfn[N], low[N], ts, stk[N], top;
vector<int> belong[N]; //边双中有哪些原始点
int id[N], dcc_cnt; //原始点x属于哪个边双连通分量,dcc_cnt指边双连通分量个数
int is_bridge[M]; //记录哪些边是割边
//链式前向星
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
//边双连通分量
void tarjan(int u, int fa) {
dfn[u] = low[u] = ++ts;
stk[++top] = u;
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (!dfn[j]) {
tarjan(j, i);
low[u] = min(low[u], low[j]);
if (dfn[u] < low[j]) is_bridge[i] = is_bridge[i ^ 1] = true; //记录割边
} else if (i != (fa ^ 1))
low[u] = min(low[u], dfn[j]);
}
if (dfn[u] == low[u]) {
++dcc_cnt; //边双数量+1
int x;
do {
x = stk[top--];
id[x] = dcc_cnt; // 记录点与边双关系
belong[dcc_cnt].push_back(x); // 记录边双中有哪些点
} while (x != u);
}
}
int main() {
scanf("%d %d", &n, &m);
memset(h, -1, sizeof h);
for (int i = 0; i < m; i++) {
int a, b;
scanf("%d %d", &a, &b);
add(a, b), add(b, a);
}
for (int i = 1; i <= n; i++)
if (!dfn[i]) tarjan(i, -1);
//输出边双个数
printf("%d\n", dcc_cnt);
// for (int i = 1; i <= dcc_cnt; i++) {
// //此边双中点的数量
// printf("%d ", belong[i].size());
// //此边双中都有哪些点
// for (int j = 0; j < belong[i].size(); j++)
// printf("%d ", belong[i][j]);
// puts("");
// }
return 0;
}