https://ac.nowcoder.com/acm/problem/51265
割点的板子
#include<iostream> #include<cstring> #include<algorithm> #include<vector> #include<queue> using namespace std; typedef long long ll; const int maxn = 1e5 + 11; vector<int>G[maxn]; void add(int x, int y) { G[x].push_back(y); } int low[maxn], dfn[maxn], df; ll siz[maxn], ans[maxn]; int cnt[maxn]; int n, m; int tarjan(int x,int root) { low[x] = dfn[x] = ++df; int flag = 0; ll sum = 0; siz[x] = 1; for (int i = 0; i < G[x].size(); i++) { int p = G[x][i]; if (!dfn[p]) { tarjan(p,root); siz[x] += siz[p]; low[x] = min(low[x], low[p]); if (low[p] >= dfn[x]) { flag++; ans[x] += 1LL * (siz[p])*(1LL * n - siz[p]); sum += siz[p]; if (flag > 1 || x != root) cnt[x] = 1; } } else { low[x] = min(low[x], dfn[p]); } } if (cnt[x]) { ans[x] += 1LL * (sum + 1)*(n - sum - 1) + n - 1; } else { ans[x] = 2 * (n - 1); } return 0; } int main() { scanf("%d%d", &n, &m); int x, y; for (int i = 0; i < m; i++) { scanf("%d%d", &x, &y); add(x, y); add(y, x); } tarjan(1, 1); for (int i = 1; i <=n; i++) { printf("%lld ", ans[i]); } return 0; }