Lydsy1123 BLO

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

#include<cstdio>
int hea[100010],nxt[1000010],to[1000010],dfn[100010],low[100010],siz[100010],tot,num,n,m;
long long ans[100010];
void add(int a,int b)
{
    nxt[++tot]=hea[a];
    hea[a]=tot;
    to[tot]=b;
}
void tarjan(int x,int rt)
{
    dfn[x]=low[x]=++num;
    siz[x]=1;
    int f=0,cut=0,s=0;
    for(int i=hea[x];i;i=nxt[i])
    {
        int y=to[i];
        if(!dfn[y])
        {
            tarjan(y,rt);
            siz[x]+=siz[y];
            low[x]=low[x]<low[y]?low[x]:low[y];
            if(low[y]>=dfn[x])
            {
                f++;
                if(f>1||x!=rt)cut=1;
                ans[x]=ans[x]+1ll*(n-siz[y])*siz[y];
                //x是个割点,去掉它后
				//它下面的子树Y中所有点,与图中其它点都不连通 
                s+=siz[y];
            }
        }
        else low[x]=low[x]<dfn[y]?low[x]:dfn[y];
    }
    if(cut)
	    ans[x]=ans[x]+1ll*(n-s-1)*(s+1)+n-1;
	//(n-s-1)代表去掉割点及它下面那些子树结点后,留下来的点
	//这些点与这(s+1)个点不连通
	//最后那个n-1是指x点本身与其它的所有点不连通 
    else 
    //如果x不是割点,则去掉它所有的边,它只与其它N-1个点不连通 
	    ans[x]=2*n-2;
}
int main()
{
    int x,y;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    tarjan(1,1);
    for(int i=1;i<=n;i++)
        printf("%lld
",ans[i]);
    return 0;
}

  

原文地址:https://www.cnblogs.com/cutemush/p/12685928.html