bzoj 1123: [POI2008]BLO

题意

Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通
输入n<=100000 m<=500000及m条边
输出n个数,代表如果把第i个点去掉,将有多少对点不能互通。

题解

这题的话,还是很好做的吧。。
在TJ的过程中,假如一点点DP的小元素就可以了
感觉这个算法还是很好理解的吧,你可以理解为随便搞一个生成树,然后再在上面加边搞事情
然后这个的话,考虑一个,割掉它就是让他返祖边不能回到他上方的子树断掉
然后把全部这样的子树拿出来
乘法原理搞一波就可以了

CODE:

#include<cstdio>
#include<vector>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
const LL N=500005;
struct qq
{
    LL x,y,last;
}e[N*2];LL num,last[N];
LL ans[N];
LL n,m;
void init (LL x,LL y)
{
    num++;
    e[num].x=x;e[num].y=y;
    e[num].last=last[x];
    last[x]=num;
}
LL low[N],dfn[N],id;
LL tot[N];//这个子树有多少人
void dfs (LL x,LL fa)
{
    tot[x]=1;low[x]=dfn[x]=++id;
    vector<int> o;
    LL cnt=0;
    LL up=0,down=0;
    for (LL u=last[x];u!=-1;u=e[u].last)
    {
        LL y=e[u].y;
        if (y==fa) continue;
        if (dfn[y]==0)
        {
            dfs(y,x);tot[x]+=tot[y];
            low[x]=min(low[x],low[y]);
            if (low[y]>=dfn[x]) 
            {
                o.push_back(y);
                down=down+tot[y];
            }
            else up=up+tot[y];
        }
        else low[x]=min(low[x],dfn[y]);
    }
    up=up+n-tot[x];
    cnt=o.size();
    if (cnt==0) return ;
    if (cnt==1&&x==1) return ;
    for (int u=0;u<cnt;u++)
    {
        int y=o[u];
        ans[x]=ans[x]+tot[y]*up*2;
        ans[x]=ans[x]+tot[y]*(down-tot[y]);
    }
}
int main()
{
    num=0;memset(last,-1,sizeof(last));
    scanf("%lld%lld",&n,&m);
    for (LL u=1;u<=m;u++)
    {
        LL x,y;
        scanf("%lld%lld",&x,&y);
        init(x,y);init(y,x);
    }
    dfs(1,0);
    for (LL u=1;u<=n;u++) printf("%lld\n",ans[u]+(n-1)*2);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值