bzoj 1123 BLO

本文介绍了一道名为BLO的问题,该问题涉及在一个由n个城镇和m条双向道路组成的连通图中,计算移除每个城镇后无法相互到达的城镇对数量。文章提供了一个基于Tarjan算法的解决方案,并附上了实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1123: [POI2008]BLO
Description
Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通。

Input
输入n<=100000 m<=500000及m条边

Output
输出n个数,代表如果把第i个点去掉,将有多少对点不能互通。

Sample Input
5 5

1 2

2 3

1 3

3 4

4 5
Sample Output
8

8

16

14

8

题解:
其实就是个tarjan求点双。
点双并不用实际求出来,只是在搜索树中传上去,遇到割点求一下即可。
注意(x,y)和(y,x)是不同对点。

附上代码:

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define int long long
#define mmin(a,b) (a<b?a:b)
struct tree{
    int u,v,next;
}l[1001000];
int n,m,lian[101000],e,ans[101000];
int dfn[101000],low[101000],num,size[101000];
void bian(int,int);
void tar(int);
signed main()
{
//  freopen("in.txt","r",stdin);
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%lld%lld",&x,&y);
        bian(x,y);
        bian(y,x);
    }
    tar(1);
    for(int i=1;i<=n;i++) printf("%lld\n",ans[i]+2*n-2);
//  while(1);
    return 0;
}
void bian(int x,int y)
{
    e++;
    l[e].u=x;
    l[e].v=y;
    l[e].next=lian[x];
    lian[x]=e;
}
void tar(int x)
{
    dfn[x]=low[x]=++num;
    size[x]=1;
    int zz=0;
    for(int i=lian[x];i;i=l[i].next)
    {
        int v=l[i].v;
        if(dfn[v]==0)
        {
            tar(v);
            size[x]+=size[v];
            low[x]=mmin(low[x],low[v]);
            if(dfn[x]<=low[v])
            {
                ans[x]+=zz*size[v]*2ll;
                zz+=size[v];
            }
        }
        else
            low[x]=mmin(dfn[v],low[x]);
    }
    ans[x]+=zz*(n-zz-1)*2ll;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值