[bzoj1123] [POI2008]BLO
Description
n个点m条边的无向连通图,无重边无自环.
求对于所有i,去掉第i个点后有多少对有序点不连通.
HINT
\(n\leq100000,m\leq500000\).
Solution
tarjan求割点的时候顺便计数即可.
#define N 100005
#define M 1000005
typedef long long ll;
struct graph{
int nxt,to;
}e[M];
ll ans[N];
int g[N],dfn[N],low[N],siz[N],n,m,cnt;
bool cut[N];
inline void tarjan(int u,int fa){
int chl=0,tot=0;
dfn[u]=low[u]=++cnt;siz[u]=1;
for(int i=g[u],c;i;i=e[i].nxt)
if(!dfn[c=e[i].to]){
tarjan(c,u);
siz[u]+=siz[c];
low[u]=min(low[u],low[c]);
if(!fa){
if(++chl>=2){
cut[u]=true;
ans[u]+=1ll*siz[c]*tot;
tot+=siz[c];
}
}
else if(low[c]>=dfn[u]){
cut[u]=true;
ans[u]+=1ll*siz[c]*tot;
tot+=siz[c];
}
}
else if(c!=fa)
low[u]=min(low[u],dfn[c]);
if(cut[u]) ans[u]+=1ll*(n-1-tot)*tot;
ans[u]+=n-1;
}
inline void addedge(int x,int y){
e[++cnt]=(graph){g[x],y};g[x]=cnt;
}
inline void Aireen(){
n=read();m=read();
for(int i=1,x,y;i<=m;++i){
x=read();y=read();
addedge(x,y);addedge(y,x);
}
for(int i=1;i<=n;++i)
if(!dfn[i]) tarjan(i,0);
for(int i=1;i<=n;++i)
printf("%lld\n",ans[i]<<1);
}
2017-10-27 13:11:29