zoukankan      html  css  js  c++  java
  • 【luogu2783】 有机化学之神偶尔会做作弊 [tarjan 缩点][LCA]

    P2783 有机化学之神偶尔会做作弊 

    缩点 然后LCA x,y两点之间的距离为dep[x]+dep[y]-2dep[lca]+1

    死于各种缩点之后忘记用bl

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int N=10000+50,M=50000+50,inf=0x3f3f3f3f;
    int n,m,q,ans=0,f[N][25],dep[N];
    int idx=0,Bcnt=0,dfn[N],low[N],bl[N];
    bool inst[N];
    stack<int>s;
    template<class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    int head[N],tot=0;
    struct edge{int u,v,nxt;}e[M<<1],e2[M<<1];
    void add(int u,int v){
        e[++tot]=(edge){u,v,head[u]};head[u]=tot;
    }
    
    void tarjan(int u,int fa){
        dfn[u]=low[u]=++idx;
        s.push(u),inst[u]=1;
        for(int i=head[u],v;i;i=e[i].nxt){
            v=e[i].v;
            if(v!=fa){
                if(!dfn[v]) tarjan(v,u),low[u]=min(low[u],low[v]);
                else if(inst[v]&&low[u]>dfn[v]) low[u]=dfn[v];    
            }
        }
        if(low[u]==dfn[u]){
            ++Bcnt;
            int v;
            do{
                v=s.top(),s.pop();
                bl[v]=Bcnt,inst[v]=0;
            }while(u!=v);
        }
    }
    
    int head2[N],tot2=0;
    void add2(int u,int v){
        e2[++tot2]=(edge){u,v,head2[u]};head2[u]=tot2;
    } 
    void dfs(int u,int fa){
        dep[u]=dep[fa]+1;
        f[u][0]=fa;
        for(int i=1;i<=20;++i){
            if(dep[u]<(1<<i)) break;
            f[u][i]=f[f[u][i-1]][i-1];
        }
        for(int i=head2[u];i;i=e2[i].nxt){
            if(e2[i].v==fa) continue;
            dfs(e2[i].v,u);
        }
    }
    int LCA(int a,int b){
        if(dep[a]>dep[b]) swap(a,b);
        for(int i=20;i>=0;--i){
            if(dep[f[b][i]]<dep[a]) continue;
            b=f[b][i];
        }
        if(b==a) return a;
        for(int i=20;i>=0;--i){
            if(f[a][i]==f[b][i]) continue;
            a=f[a][i],b=f[b][i];
        }
        return f[a][0];
    }
    
    void print(int x){
        int num[N];
        memset(num,0,sizeof(num));
        if(!x) {puts("0");return;}
        if(x<0) {putchar('-');x=0-x;}
        while(x) num[++num[0]]=(x&1),x>>=1;
        for(int i=num[0];i>0;--i) printf("%d",num[i]);
        printf("
    ");
    }
    
    int main(){
        //freopen("in.txt","r",stdin);
        rd(n),rd(m);
        for(int i=1,u,v;i<=m;++i) rd(u),rd(v),add(u,v),add(v,u);
        for(int i=1;i<=n;++i)
        if(!dfn[i]) tarjan(i,0);
        for(int i=1;i<=m;++i)
        if(bl[e[i<<1].u]!=bl[e[i<<1].v]) add2(bl[e[i<<1].u],bl[e[i<<1].v]),add2(bl[e[i<<1].v],bl[e[i<<1].u]);
        rd(q);
        dfs(1,0);
        for(int i=1,x,y,lca;i<=q;++i){
            rd(x),rd(y),lca=LCA(bl[x],bl[y]);
            print(dep[bl[x]]+dep[bl[y]]-dep[lca]*2+1);
        }
        return 0;
    }
  • 相关阅读:
    centos编辑文件显示行号
    16.1
    [整理]正睿划水记
    [题解]UVA1519 Dictionary Size
    [题解]CF323C Two permutations
    [题解]CF1527D MEX Tree
    P2216 [HAOI2007]理想的正方形
    CF858D Polycarp's phone book
    ABC214F substrings
    每天一点小知识-20210810
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11161685.html
Copyright © 2011-2022 走看看