434 words
2 minutes
Block-Cut Tree Template
// Eating, bathing, having a girlfriend, having an active social life is incidental, it gets in the way of code time.
// Writing code is the primary force that drives our lives so anything that interrupts that is wasteful.
#include <bits/stdc++.h>
using namespace std;
/************************************/
inline int64_t read() { int64_t x = 0, f = 1; char ch = getchar(); while (ch<'0'|| ch>'9') { if(ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar();} return x * f; }
inline int read(char *s) { char ch = getchar(); int i = 1; while (ch == ' ' || ch == '\n') ch = getchar(); while (ch != ' ' && ch != '\n') s[i++] = ch, ch = getchar(); s[i] = '\0'; return i - 1; }
#define fileio(x) freopen((string(x) + ".in").c_str(), "r", stdin), freopen((string(x) + ".out").c_str(), "w", stdout)
typedef int64_t ll; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef long double ld;
ll mod = 1e9 + 7;
#define fi first
#define se second
inline int64_t min(int64_t a, int64_t b) { return a < b ? a : b; } inline int64_t max(int64_t a, int64_t b) { return a > b ? a : b; }
ll fpow(ll a, ll b, ll md, ll cur = 1) { while (b) { { if (b % 2 == 1) cur *= a; } a *= a, b = b / 2, a %= md, cur %= md; } return cur % md; }
/************************************/
const ll N = 2e5 + 5;
ll n, m;
vector<int> G[N];
vector<int> T[N << 1];
namespace blockcuttree {
int dfn[N << 1], low[N], dfc, cnt;
int stk[N], tp;
void Tarjan(int u) {
low[u] = dfn[u] = ++dfc;
stk[++tp] = u;
for (int v : G[u]) {
if (!dfn[v]) {
Tarjan(v);
low[u] = min(low[u], low[v]);
if (low[v] == dfn[u]) {
cnt++;
for (int x = 0; x != v; --tp) {
x = stk[tp];
T[cnt].push_back(x);
T[x].push_back(cnt);
}
T[cnt].push_back(u);
T[u].push_back(cnt);
}
} else
low[u] = min(low[u], dfn[v]);
}
}
}
using namespace blockcuttree;
signed main() {
n = read(), m = read();
for (int i = 1; i <= n; i++)
G[i].clear(), dfn[i] = 0, low[i] = 0;
for (int i = 1; i <= m; i++) {
int u = read(), v = read();
G[u].push_back(v), G[v].push_back(u);
}
cnt = n, dfc = 0;
for (int i = 1; i <= n; i++)
if (!dfn[i])
Tarjan(i), tp--;
// here, G is the original, T is the new graph.
}