tarjan求割点计算答案。注意不是每一棵子树都算答案。开个变量记一下。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 100050 #define maxe 1000050 using namespace std; long long n,m,x,y,g[maxv],nume=0,dfn[maxv],low[maxv],stack[maxv],top=0,size[maxv],times=0,base=0,ans[maxv]; bool vis[maxv]; struct edge { long long v,nxt; }e[maxe]; void addedge(long long u,long long v) { e[++nume].v=v; e[nume].nxt=g[u]; g[u]=nume; } void dfs(long long x) { dfn[x]=low[x]=++times;size[x]=1;long long t=0;vis[x]=true; for (long long i=g[x];i;i=e[i].nxt) { long long v=e[i].v; if (!vis[v]) { dfs(v); size[x]+=size[v];low[x]=min(low[x],low[v]); if (((dfn[x]<=low[v]) && (x!=1)) || ((x==1) && (base>1))) { stack[++top]=x; ans[x]+=t*size[v]; t+=size[v]; } } else low[x]=min(low[x],dfn[v]); } ans[x]+=(n-t-1)*t; ans[x]*=2; } int main() { scanf("%lld%lld",&n,&m); for (long long i=1;i<=m;i++) { scanf("%lld%lld",&x,&y); addedge(x,y);addedge(y,x); if ((x==1) || (y==1)) base++; } dfs(1); sort(stack+1,stack+top+1); base=unique(stack+1,stack+top+1)-stack-1; long long p=1; for (long long i=1;i<=n;i++) { if (stack[p]==i) { printf("%lld\n",2*(n-1)+ans[i]); p++; } else printf("%lld\n",(n-1)*2); } return 0; }