分析
我们知道对于一个割点,我们如果去掉它就会使原来的图被分为若干块,则这是我们将所有块包含的点的个数两两相乘即可,而如果不是割点则对于图的连通性没有影响。注意在最后要加上2*(n-1)表示去掉的那个点对答案产生的贡献。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
long long dfn[100010],low[100010],cnt,sum,siz[100010];
long long ans[100010],n,m;
vector<long long>v[100010];
inline void tarjan(long long x,long long la){
siz[x]=1;
dfn[x]=low[x]=++cnt;
long long son=0,tot=0;
for(long long i=0;i<v[x].size();i++)
if(v[x][i]!=la){
if(!dfn[v[x][i]]){
son++;
tarjan(v[x][i],x);
siz[x]+=siz[v[x][i]];
low[x]=min(low[x],low[v[x][i]]);
if(dfn[x]<=low[v[x][i]]){
ans[x]+=siz[v[x][i]]*tot;
tot+=siz[v[x][i]];
}
}else low[x]=min(low[x],dfn[v[x][i]]);
}
ans[x]+=tot*(n-tot-1);
if(son==1&&!la)ans[x]=0;
}
int main(){
long long i,j,k;
scanf("%lld%lld",&n,&m);
for(i=1;i<=m;i++){
long long x,y;
scanf("%lld%lld",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
for(i=1;i<=n;i++)
if(!dfn[i])tarjan(i,0);
for(i=1;i<=n;i++)printf("%lld
",(ans[i]+n-1)*2);
return 0;
}