BZOJ1123 BLO [Tarjan][点双连通分量]

4 篇文章 0 订阅

就是点双连通分量的裸题,我们记录一个siz,如果某个点可以搜到low比它的deep值大的点的话,显然是产生了一个分割后的连通块。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#define pa pair<int,int>
#define inf 1000000000
#define ll long long 
using namespace std;
inline void read(int &res){
    int flag=1;static char ch;
    while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;
}
int n,m,cnt,tot;
int head[100005],size[100005],dfn[100005],low[100005];
ll ans[100005];
struct data{
int to,next;
}E[1000005];
void addedge(int u,int v){
    E[++tot].to=v;E[tot].next=head[u];head[u]=tot;
    E[++tot].to=u;E[tot].next=head[v];head[v]=tot;
}
void tarjan(int x){
    int t=0;
    size[x]=1;
    dfn[x]=low[x]=++cnt;
    for(int i=head[x];i;i=E[i].next)
        if(dfn[E[i].to])low[x]=min(low[x],dfn[E[i].to]);
        else{
            tarjan(E[i].to);
            size[x]+=size[E[i].to];
            low[x]=min(low[x],low[E[i].to]);
            if(dfn[x]<=low[E[i].to]){
                ans[x]+=(ll)t*size[E[i].to];
                t+=size[E[i].to];
            }
        }
    ans[x]+=(ll)t*(n-t-1);
}
int main(){
    read(n),read(m);
    for(int u,v,i=1;i<=m;i++)
        read(u),read(v),addedge(u,v);
    tarjan(1);
    for(int i=1;i<=n;i++)
        printf("%lld\n",(ans[i]+n-1)*2);
    return 0;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值