[bzoj1123]BLO
割点版子改一下。 之后大概写个各种tarjan算法的blog吧。
- 代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,M=1e6+5;
int hed[N],to[M],nxt[M],cnt;
void adde(int u,int v){
cnt++;to[cnt]=v,nxt[cnt]=hed[u];hed[u]=cnt;
}
int n,m;
int num,dfn[N],low[N],sz[N]; ll ans[N];
bool cut[N];
inline void tarjan(int u){
dfn[u]=low[u]=++num;sz[u]=1;
int flag=0,sum=0;
for(int i=hed[u];i;i=nxt[i]){
int v=to[i];
if(!dfn[v]){
tarjan(v);
sz[u]+=sz[v];
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]){
flag++;
sum+=sz[v];
ans[u]+=1ll*sz[v]*(n-sz[v]);
if(u!=1||flag>1)cut[u]=true;
}
}
else low[u]=min(low[u],dfn[v]);
}
if(!cut[u])ans[u]=2ll*(n-1);
else ans[u]+=1ll*(n-1)+1ll*(n-sum-1)*1ll*(sum+1);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v;scanf("%d%d",&u,&v);
if(u==v)continue;
adde(u,v);adde(v,u);
}
tarjan(1);
for(int i=1;i<=n;i++)
printf("%lld\n",ans[i]);
}