BLO-Blockade
若一个点为割点:统计出每个子树的大小,两两相乘再相加,
再加上n-1,为这个点与其他点的拜访数,
因为拜访是互相的,最后再乘二即可
若一个点不是割点:只有(n-1)*2次拜访会受影响
#include<cstdio> #define LL long long #define N 100010 #define M 1000010 #define min(a,b) ((a)<(b)?(a):(b)) int n,m,dfn[N],low[N],size[N],cnt; LL ans[N]; const int ch_top=4e7+3; char ch[ch_top],*now_r=ch-1,*now_w=ch-1; inline int read(){ while(*++now_r<'0'); register int x=*now_r-'0'; while(*++now_r>='0')x=x*10+*now_r-'0'; return x; } inline void write ( LL x ) { static char st[20] ; static int top ; if ( x < 0 ) *++now_w = '-' , x *= -1 ; while( st[++top] = x % 10 ^ 48 , x /= 10 ) ; while( *++now_w = st[top] , --top ); *++now_w = ' ' ; } int Head[N],num; struct NODE{ int to,next; } e[M]; void Tarjan(int u){ dfn[u]=low[u]=++cnt; size[u]=1; int t=0; for(int i=Head[u];i;i=e[i].next){ int v=e[i].to; if(!dfn[v]){ Tarjan(v); size[u]+=size[v]; low[u]=min(low[u],low[v]); if(low[v]>=dfn[u]){ ans[u]+=(LL)t*size[v]; t+=size[v]; } } else low[u]=min(low[u],dfn[v]); } if(n-t-1>0) ans[u]+=(LL)(n-t-1)*t; } int main() { fread(ch,1,ch_top,stdin); n=read(); m=read(); int x,y; for(int i=1;i<=m;i++){ x=read(); y=read(); e[++num].to=y; e[num].next=Head[x]; Head[x]=num; e[++num].to=x; e[num].next=Head[y]; Head[y]=num; } Tarjan(1); for(int i=1;i<=n;i++) write((ans[i]+n-1)<<1); fwrite(ch,1,now_w-ch,stdout); return 0; }