bzoj 1123 BLO

来源:互联网 发布:美国滑板鞋牌子 知乎 编辑:程序博客网 时间:2024/04/29 22:25

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;}
原创粉丝点击