hdu5458 LCA+并查集+dfs序+树状数组

来源:互联网 发布:san网络 nas存储 编辑:程序博客网 时间:2024/04/28 00:02

神题,看着别人代码学习

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>#include<string>#include<iomanip>#include<vector>#include<set>#include<map>#include<queue>using namespace std;typedef long long LL;typedef unsigned long long ULL;#define rep(i,k,n) for(int i=(k);i<=(n);i++)#define rep0(i,n) for(int i=0;i<(n);i++)#define red(i,k,n) for(int i=(k);i>=(n);i--)#define sqr(x) ((x)*(x))#define clr(x,y) memset((x),(y),sizeof(x))#define pb push_back#define mod 1000000007const int maxn=30010;const int maxq=100010;const int N=15;int n,m,q;int fa[maxn][N];int beg[maxn],ed[maxn],dtime,dep[maxn],ans[maxq];struct edge{    int to,del;    edge(int x):to(x),del(0){}    bool operator < (const edge &x) const    {        if(to!=x.to)return to<x.to;        return del>x.del;    }};vector<edge> e[maxn];struct QUERY{    int op,u,v;    void read()    {        scanf("%d%d%d",&op,&u,&v);        if(op==1)        {            lower_bound(e[u].begin(),e[u].end(),edge(v))->del=1;            lower_bound(e[v].begin(),e[v].end(),edge(u))->del=1;        }    }}Q[maxq];struct BIT{    int v[maxn];    void init()    {        clr(v,0);    }    void add(int x,int k)    {        for(;x<=n;x+=x&-x)v[x]+=k;    }    void update(int L,int R,int k)    {        add(L,k);        add(R+1,-k);    }    int qry(int x)    {        int ret=0;        for(;x;x-=x&-x)ret+=v[x];        return ret;    }}B;void dfs(int u,int F,int deep){    if(F)e[u].erase(lower_bound(e[u].begin(),e[u].end(),edge(F)));    beg[u]=++dtime;    dep[u]=deep;    fa[u][0]=F;    for(int i=0;i<e[u].size();i++)    {        if(e[u][i].del || beg[e[u][i].to])continue;        e[u][i].del=1;        dfs(e[u][i].to,u,deep+1);    }    ed[u]=dtime;    B.update(beg[u],ed[u],1);}void Lca_init(){    for(int i=1;i<N;i++)rep(j,1,n)fa[j][i]=fa[fa[j][i-1]][i-1];}int lca(int u,int v){    if(dep[u]<dep[v])swap(u,v);    int t=dep[u]-dep[v];    for(int i=0;i<N;i++)if((1<<i)&t)u=fa[u][i];    if(u==v)return u;    for(int i=N-1;i>=0;i--)    {        if(fa[u][i]!=fa[v][i])        {            u=fa[u][i];            v=fa[v][i];        }    }    return fa[u][0];}struct UNION{    int f[maxn];    void init()    {        rep(i,1,n)f[i]=i;        rep(i,1,n)for(int j=0;j<e[i].size();j++)        {            if(e[i][j].del)continue;            merge(i,e[i][j].to);        }    }    int getf(int x)    {        return x==f[x]?x:f[x]=getf(f[x]);    }    void mergef(int u,int ff)    {        while(u!=ff)        {            int t=getf(fa[u][0]);            f[u]=t;            B.update(beg[u],ed[u],-1);            u=t;        }    }    void merge(int u,int v)    {        u=getf(u);        v=getf(v);        int ff=getf(lca(u,v));        mergef(u,ff);        mergef(v,ff);    }}U;void solve(){    clr(beg,0);clr(ed,0);    B.init();    dtime=0;    dfs(1,0,1);    Lca_init();    U.init();    int tot=0;    red(i,q,1)    {        int u=U.getf(Q[i].u),v=U.getf(Q[i].v);        if(Q[i].op==1)        {            U.merge(u,v);        }        else        {            int ff=U.getf(lca(u,v));            ans[++tot]=B.qry(beg[u])+B.qry(beg[v])-2*B.qry(beg[ff]);        }    }    red(i,tot,1)printf("%d\n",ans[i]);}int main(){int T;scanf("%d",&T);rep(ii,1,T){    printf("Case #%d:\n",ii);    scanf("%d%d%d",&n,&m,&q);    rep(i,1,n)e[i].clear();    rep(i,1,m)    {        int u,v;        scanf("%d%d",&u,&v);        e[u].pb(edge(v));        e[v].pb(edge(u));    }    rep(i,1,n)sort(e[i].begin(),e[i].end());    rep(i,1,q)Q[i].read();    solve();}return 0;}


0 0
原创粉丝点击