BZOJ1123: [POI2008]BLO

来源:互联网 发布:电脑免费视频编辑软件 编辑:程序博客网 时间:2024/05/17 22:26

题目链接

【分析】

(这种清新脱俗的题面看起来就是爽啊。。)

tarjan求割点
把某个割点去掉以后,会出现几个连通块,它们之间不能互相到达
即会分成上面一棵树,下面若干子树
子树之间不互通,所有子树和上面那个树不互通,通过记录树的大小统计答案
另外删去的点和其它点不互通

【代码】

#include <cstdio>#include <iostream>#include <queue>#include <vector>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#define N 100005#define M 1000005#define INF 1000000000using namespace std;typedef long long ll;typedef pair<ll,ll> pa;int read(){    int x=0,f=1;char ch=getchar();    while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}    while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}    return x*f;}int n,m,ind,scc,cnt;int b[M],p[N],nextedge[M];int dfn[N],low[N],Belong[N],sz[N];ll ans[N];bool Instack[N];stack<int>st;void Add(int x,int y){    cnt++;    b[cnt]=y;    nextedge[cnt]=p[x];    p[x]=cnt;}void Anode(int x,int y){    Add(x,y);Add(y,x);}void Input_Init(){    n=read();m=read();    for(int i=1;i<=m;i++)    {        static int x,y;        x=read(),y=read();        Anode(x,y);    }}void Tarjan(int x){    dfn[x]=low[x]=++ind;    int child=0;    sz[x]=1;    for(int i=p[x];i;i=nextedge[i])    {        int v=b[i];        if(!dfn[v])        {            Tarjan(v);            sz[x]+=sz[v];            low[x]=min(low[x],low[v]);            if(dfn[x]<=low[v])            {                ans[x]+=(ll)child*sz[v];                child+=sz[v];            }        }        else low[x]=min(low[x],dfn[v]);    }    ans[x]+=(ll)child*(n-child-1);}void Solve(){    Tarjan(1);    for(int i=1;i<=n;i++) printf("%lld\n",(ans[i]+n-1)<<1);}int main(){    Input_Init();    Solve();    return 0;}
0 0
原创粉丝点击