bzoj3331: [BeiJing2013]压力

做完算进以后回来看这题简直sb

点双+LCA+树上差分即可

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;

struct node
{
    int x,y,next;
}a[810000];int len,last[210000];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}
int z,rt,dfn[210000],low[210000];
int top,sta[210000];
int cnt,bel[210000];
vector<int>vec[210000];bool cut[210000];
void v_DCC(int x)
{
    dfn[x]=low[x]=++z;
    sta[++top]=x;
    int flag=0;
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(dfn[y]==0)
        {
            v_DCC(y);
            low[x]=min(low[x],low[y]);
            if(dfn[x]<=low[y])
            {
                flag++;if(flag>1||x!=rt)cut[x]=true;
                int k;cnt++;
                do
                {
                    k=sta[top];top--;
                    vec[cnt].push_back(k);
                }while(k!=y);
                vec[cnt].push_back(x);
            }
        }
        else low[x]=min(low[x],dfn[y]);
    }
}

//-----------------v-DCC-------------------------

node e[810000];int elen,elast[210000];
void eins(int x,int y)
{
    elen++;
    e[elen].x=x;e[elen].y=y;
    e[elen].next=elast[x];elast[x]=elen;
}
int Bin[25];
int f[25][210000],dep[210000];
void dfs(int x)
{
    for(int i=1;dep[x]>=Bin[i];i++)f[i][x]=f[i-1][f[i-1][x]];
    
    for(int k=elast[x];k;k=e[k].next)
    {
        int y=e[k].y;
        if(y!=f[0][x])
        {
            f[0][y]=x;
            dep[y]=dep[x]+1;
            dfs(y);
        }
    }
}
int LCA(int x,int y)
{
    int w=-1;
    if(dep[x]<dep[y]){swap(x,y);w=1;}
    for(int i=22;i>=0;i--)
        if(dep[x]-dep[y]>=Bin[i])x=f[i][x];
    if(x==y)return x;
    for(int i=22;i>=0;i--)
        if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y])x=f[i][x],y=f[i][y];
    return f[0][x];
}

int d[210000];
void dfs2(int x)
{
    for(int k=elast[x];k;k=e[k].next)
    {
        int y=e[k].y;
        if(y!=f[0][x])
        {
            dfs2(y);
            d[x]+=d[y];
        }
    }
}
int id[210000],as[210000];
int main()
{
    freopen("vcc.in","r",stdin);
    freopen("vcc.out","w",stdout);
    int n,m,Q,x,y;
    scanf("%d%d%d",&n,&m,&Q);
    len=0;memset(last,0,sizeof(last));
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        ins(x,y),ins(y,x);
    }
    z=cnt=0;
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(cut,false,sizeof(cut));
    for(int i=1;i<=n;i++)
        if(dfn[i]==0)rt=i,v_DCC(i);
        
    int num=cnt;
    for(int i=1;i<=n;i++)
        if(cut[i]==true)id[i]=++cnt,bel[i]=cnt;
    elen=0;memset(elast,0,sizeof(elast));
    for(int i=1;i<=num;i++)
        for(int j=0;j<vec[i].size();j++)
        {
            int x=vec[i][j];
            if(cut[x]==true)
            {
                eins(id[x],i);
                eins(i,id[x]);
            }
            else bel[x]=i;
        }
    Bin[0]=1;for(int i=1;i<=22;i++)Bin[i]=Bin[i-1]*2;
    f[0][1]=0;dep[1]=0;dfs(1);
    
    memset(as,0,sizeof(as));
    memset(d,0,sizeof(d));
    while(Q--)
    {
        scanf("%d%d",&x,&y);as[x]++,as[y]++;
        x=bel[x],y=bel[y];
        int lca=LCA(x,y);
        d[x]++,d[y]++;d[lca]--;
        if(lca!=1)
        {
            d[f[0][lca]]--;
            if(f[0][lca]==0)
            {
                int t;t++;
            }
        }
    }
    dfs2(1);
    for(int i=1;i<=n;i++)
        printf("%d\n",(cut[i])?d[id[i]]:as[i]);
    return 0;
}

 

posted @ 2018-03-21 15:17  AKCqhzdy  阅读(270)  评论(0编辑  收藏  举报