• LCA


    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int maxn=50010;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=10*x+ch-'0';ch=getchar();}
        return x*f;
    }
    int first[maxn],to[2*maxn],next[2*maxn],val[2*maxn],cnt;
    int st[maxn][50];
    int vis[maxn];
    int dis[maxn];
    int depth[maxn],f[maxn];
    void add(int a,int b,int c)
    {
        to[++cnt]=b;
        next[cnt]=first[a];
        first[a]=cnt;
        val[cnt]=c;
    }
    void ins(int a,int b,int c){add(a,b,c);add(b,a,c);}
    void dfs(int x)
    {
        st[x][0]=f[x];
        for(int i=1;i<=31;i++)st[x][i]=st[st[x][i-1]][i-1];
        for(int i=first[x];i;i=next[i])
        {
            if(to[i]==f[x])continue;
            f[to[i]]=x;
            depth[to[i]]=depth[x]+1;
            dis[to[i]]=val[i]+dis[x];
            dfs(to[i]);
        }
    }
    pair<int,int> lca(int u,int v)
    {
        int a=u,b=v;
        if(depth[u]<depth[v])swap(u,v),swap(a,b);
        for(int i=31;i>=0;i--)
            if(depth[v]<depth[st[u][i]])u=st[u][i];
        
        if(u==v)return make_pair(v,dis[a]-dis[v]);
        for(int i=31;i>=0;i--)
        {
            if(st[u][i]==st[v][i])break;
            u=st[u][i],v=st[v][i];
        }
        return make_pair(st[u][0],dis[a]+dis[b]-(dis[st[u][0]]<<1));
    }
    int main()
    {
        int n,q;
        scanf("%d",&n);
        for(int i=1;i<n;i++)
        {
            int u=read(),v=read(),w=read();
            ins(u,v,w);
        }
        depth[1]=1;
        vis[1]=1;
        dfs(1);
        q=read();
        pair<int,int> ans;
        for(int i=1;i<=q;i++)
        {
            int u,v;
            u=read(),v=read();
            ans=lca(u,v);
            cout<<ans.first<<" "<<ans.second<<endl;
        }
    }
    倍增
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int maxn=50010;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=10*x+ch-'0';ch=getchar();}
        return x*f;
    }
    int first[maxn],to[2*maxn],next[2*maxn],val[2*maxn],cnt;
    int qfirst[maxn],qto[2*maxn],qnext[2*maxn],qval[2*maxn],qcnt,qdis[2*maxn],idq[maxn];
    int n,q; 
    int vis[maxn];
    int depth[maxn],fa[maxn];
    int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    void Unite(int x,int y){if(find(x)!=find(y))fa[find(x)]=find(y);}
    void add(int a,int b)
    {
        to[++cnt]=b;
        next[cnt]=first[a];
        first[a]=cnt;
    }
    void ins(int a,int b){add(a,b);add(b,a);}
    void qadd(int a,int b)
    {
        qto[++qcnt]=b;
        qnext[qcnt]=qfirst[a];
        qfirst[a]=qcnt;
    }
    void qins(int a,int b){qadd(a,b);qadd(b,a);}
    
    void Tarjan_dfs(int x,int f)
    {
        int lca;
        fa[x]=x;
        vis[x]=1;
        for(int i=first[x];i;i=next[i])
        {
            if(to[i]==f)continue;
            vis[to[i]]=1;
            depth[to[i]]=depth[x]+1;
            Tarjan_dfs(to[i],x);
            Unite(to[i],x);
        }
        for(int i=qfirst[x];i;i=qnext[i])
        {
            if(vis[qto[i]])
            {
                lca=find(qto[i]);
                qval[idq[i]]=lca;
                qdis[idq[i]]=depth[qto[i]]+depth[x]-(depth[lca]<<1);
            }
        }
    }
    int main()
    {
        n=read(),q=read();
        int u,v;
        for(int i=1;i<n;i++)
        {
            u=read(),v=read();
            ins(u,v);
        }
        for(int i=1;i<=n;i++)fa[i]=i;
        for(int i=1;i<=q;i++)
        {
            u=read(),v=read();
            qadd(u,v);idq[qcnt]=i;
            qadd(v,u);idq[qcnt]=i;
        }
        depth[1]=1;
        Tarjan_dfs(1,1);
        for(int i=1;i<=q;i++)cout<<qval[i]<<endl;
    }
    Tarjan
  • 相关阅读:
    IntelliJ IDEA 2017 注册方法
    WindowsAll下安装与破解IntelliJ IDEA2017
    JPA的一对多映射(双向)关联
    JPA 单向一对多关联关系
    JPA 映射单向多对一的关联关系
    关于数据库主键和外键
    JPA(API)
    X509 文件扩展名
    linux设置支持中文
    wp8安装SSL证书
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/7766675.html
Copyright © 2020-2023  润新知