就是求割点了。(像我这样的菜鸡都会啊)如果屡错的同学请去看看discuss(捂脸)
然而有个坑点就是把这个点炸了以后,他的子树也会分成几块。。。又没写lld见祖宗
记录一下当前的tot,然后无脑直接搞答案就行了。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; int n,m; struct node { int x,y,next; }a[1100000];int len,last[110000]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } int z,dfn[110000],low[110000]; int tot[110000];LL as[110000]; void tarjan(int x,int fa) { dfn[x]=low[x]=++z; tot[x]=1;int t=0; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(dfn[y]==0) { tarjan(y,x); low[x]=min(low[x],low[y]); tot[x]+=tot[y]; if(dfn[x]<=low[y]) { as[x]+=(LL(t))*(LL(tot[y]))*2LL; t+=tot[y]; } } else if(y!=fa) low[x]=min(low[x],dfn[y]); } as[x]+=(LL(t))*(LL(n-t-1))*2LL; } int main() { int x,y; scanf("%d%d",&n,&m); len=0;memset(last,0,sizeof(last)); for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); ins(x,y);ins(y,x); } z=0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(as,0,sizeof(as)); tarjan(1,0); for(int i=1;i<=n;i++)printf("%lld ",as[i]+(n-1)*2LL); return 0; }