【分析】
(这种清新脱俗的题面看起来就是爽啊。。)
tarjan求割点
把某个割点去掉以后,会出现几个连通块,它们之间不能互相到达
即会分成上面一棵树,下面若干子树
子树之间不互通,所有子树和上面那个树不互通,通过记录树的大小统计答案
另外删去的点和其它点不互通
【代码】
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#define N 100005
#define M 1000005
#define INF 1000000000
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pa;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m,ind,scc,cnt;
int b[M],p[N],nextedge[M];
int dfn[N],low[N],Belong[N],sz[N];
ll ans[N];
bool Instack[N];
stack<int>st;
void Add(int x,int y)
{
cnt++;
b[cnt]=y;
nextedge[cnt]=p[x];
p[x]=cnt;
}
void Anode(int x,int y){
Add(x,y);Add(y,x);
}
void Input_Init()
{
n=read();m=read();
for(int i=1;i<=m;i++)
{
static int x,y;
x=read(),y=read();
Anode(x,y);
}
}
void Tarjan(int x)
{
dfn[x]=low[x]=++ind;
int child=0;
sz[x]=1;
for(int i=p[x];i;i=nextedge[i])
{
int v=b[i];
if(!dfn[v])
{
Tarjan(v);
sz[x]+=sz[v];
low[x]=min(low[x],low[v]);
if(dfn[x]<=low[v])
{
ans[x]+=(ll)child*sz[v];
child+=sz[v];
}
}
else low[x]=min(low[x],dfn[v]);
}
ans[x]+=(ll)child*(n-child-1);
}
void Solve()
{
Tarjan(1);
for(int i=1;i<=n;i++) printf("%lld\n",(ans[i]+n-1)<<1);
}
int main()
{
Input_Init();
Solve();
return 0;
}