BZOJ 1123 BLO

Posted on 2016-09-01 13:08  ziliuziliu  阅读(124)  评论(0编辑  收藏  举报

tarjan求割点计算答案。注意不是每一棵子树都算答案。开个变量记一下。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxv 100050
#define maxe 1000050
using namespace std;
long long n,m,x,y,g[maxv],nume=0,dfn[maxv],low[maxv],stack[maxv],top=0,size[maxv],times=0,base=0,ans[maxv];
bool vis[maxv];
struct edge
{
    long long v,nxt;
}e[maxe];
void addedge(long long u,long long v)
{
    e[++nume].v=v;
    e[nume].nxt=g[u];
    g[u]=nume;
}
void dfs(long long x)
{
    dfn[x]=low[x]=++times;size[x]=1;long long t=0;vis[x]=true;
    for (long long i=g[x];i;i=e[i].nxt)
    {
        long long v=e[i].v;
        if (!vis[v])
        {
            dfs(v);
            size[x]+=size[v];low[x]=min(low[x],low[v]);
            if (((dfn[x]<=low[v]) && (x!=1)) || ((x==1) && (base>1)))
            {
                stack[++top]=x;
                ans[x]+=t*size[v];
                t+=size[v];
            }
        }
        else low[x]=min(low[x],dfn[v]);
    }
    ans[x]+=(n-t-1)*t;
    ans[x]*=2;
}
int main()
{
    scanf("%lld%lld",&n,&m);
    for (long long i=1;i<=m;i++)
    {
        scanf("%lld%lld",&x,&y);
        addedge(x,y);addedge(y,x);
        if ((x==1) || (y==1)) base++;
    }
    dfs(1);
    sort(stack+1,stack+top+1);
    base=unique(stack+1,stack+top+1)-stack-1;
    long long p=1;
    for (long long i=1;i<=n;i++)
    {
        if (stack[p]==i)
        {
            printf("%lld\n",2*(n-1)+ans[i]);
            p++;
        }
        else printf("%lld\n",(n-1)*2);
    }
    return 0;
}