structEdge { int from; int to; int nxt; } edge[MAXN * 4]; int head[MAXN]; int dfn[MAXN], col[MAXN], low[MAXN], siz[MAXN], tsize[MAXN]; int p2[MAXN * 2]; int n, m, cnt, depth, scnt; bool cut[MAXN * 4]; vector<int> G[MAXN]; ll dp[MAXN][2]; ll ans;
voidlink(int u, int v) { edge[++cnt].nxt = head[u]; edge[cnt].to = v; edge[cnt].from = u; head[u] = cnt; }
voidtarjan(int x, int fa) { dfn[x] = low[x] = ++depth; for (int i = head[x]; i; i = edge[i].nxt) { int to = edge[i].to; if (!dfn[to]) { tarjan(to, x); low[x] = min(low[x], low[to]); if (dfn[x] < low[to]) { // 双向边都要标记 cut[i] = cut[((i + 1) ^ 1) - 1] = 1; } } elseif (dfn[to] < dfn[x] && to != fa) { low[x] = min(low[x], dfn[to]); } } }
voidpaint(int x) { col[x] = scnt, siz[scnt]++; for (int i = head[x]; i; i = edge[i].nxt) { int to = edge[i].to; if (cut[i] or col[to]) continue; paint(to); } }