树上倍增lca,只能得60分,向大佬们求助,是在找不出哪里有错误了
查看原帖
树上倍增lca,只能得60分,向大佬们求助,是在找不出哪里有错误了
500585
siusiu楼主2022/11/19 17:26
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10,ed=2*N;
struct rec{
  int s;
  int e;
}edge[ed];                          //edge数组记录边,用链式前向星存储图
int nex[ed],in=0;               
int head[N];                      
int guanlian[N],n,m,u,v,f[N][20]
int depth[N],lg[N],qua[N];  
//guanlian[i]=x表示i号点有x条边关联,f数组是倍增lca,lg[i]=log 2 i   qua[i]=x记录i号节点到根节点的距离,相当于前缀和
void push(int num)           //             把num号边加入邻接表
{
    nex[num]=head[edge[num].s];
    head[edge[num].s]=num;
    guanlian[edge[num].s]++;
}

void dfs(int n,int fa)               //将无向图以1号节点为根建树
{
    depth[n]=depth[fa]+1;
    f[n][0]=fa;
    qua[n]=qua[fa]+guanlian[n];
    for(int i=1;i<=lg[depth[n]];i++)
        f[n][i]=f[f[n][i-1]][i-1];
    for(int i=head[n];i!=0;i=nex[i])
        if(edge[i].e!=fa)  dfs(edge[i].e,n);

}


int lca(int u,int v)          //倍增求lca
{

    if(depth[u]>depth[v])
    {
        int t=u;
        u=v;
        v=t;
    }
    int dis=depth[v]-depth[u];
    while(dis>0)
    {

        v=f[v][lg[dis]];
        dis-=pow(2,lg[dis]);

    }
   if(u==v) return u;
    while(f[u][0]!=f[v][0])
    {
          dis=depth[u];
        for(int i=lg[dis];i>=0;i--)
        {
            if(f[u][i]!=f[v][i])
            {
                u=f[u][i];
                v=f[v][i];
                break;
            }
        }
    }
    return f[u][0];
}
int main()
{
    cin>>n>>m;
    lg[1]=0;
    lg[0]=-0x3f3f3f3f;
    int pre=1,zhi=0;
    for(int i=2;i<=N;i++)           //lg数组初始化
    {
        if(i==2*pre)
        {
            lg[i]=zhi+1;
            ++zhi;
            pre=i;
        }
        else lg[i]=lg[i-1];
    }
    //for(long long int i=0;i<ed;i++) nex[i]=0;
    //for(long long int i=0;i<N;i++) guanlian[i]=0;
    for(int i=1;i<=n-1;i++)
    {
        int s,e;
        cin>>s>>e;
        ++in;
        edge[in].s=s;
        edge[in].e=e;
        push(in);
        ++in;
        edge[in].s=e;
        edge[in].e=s;
        push(in);
    }
    depth[0]=0;
    dfs(1,0);               //建树
    for(int i=1;i<=m;i++)
    {
        cin>>u>>v;
        if(u==v) cout<<1<<endl;
        else
        {
            int l=lca(u,v);
            cout<<qua[u]+qua[v]-2*qua[l]+guanlian[l]<<endl;
        }
    }
    return 0;
}
2022/11/19 17:26
加载中...