ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021.8.21 北中暑训

2021-08-21 23:31:40  阅读:134  来源: 互联网

标签:cnt int 2021.8 北中 head 1000001 next 暑训 sd


上午,学习了倍增求LCA

例题

看了题目我先是把树剖lca代码打了(因为树剖的代码比较好理解)

代码如下:

#include<bits/stdc++.h>
using namespace std;
int cnt,n,m,s,dd[1000001],zs[1000001],f[1000001],sd[1000001],ss[1000001],maxn,next[1000001],head[1000001],to[1000001];
inline void add(register int u,register int v)
{
    next[++cnt]=head[u];
    head[u]=cnt;
    to[cnt]=v;
}
int js(int x,int y,int z)
{
    f[x]=y;
    sd[x]=z;
    ss[x]=1;
    maxn=-1;
    for(int i=head[x];i!=0;i=next[i])
    {
        if(to[i]!=y)
        {
            ss[x]+=js(to[i],x,z+1);
            if(ss[to[i]]>maxn)
            {
                maxn=ss[to[i]];
                zs[x]=to[i];
            }
        }
    }
    return ss[x];
}
void lb(int x,int y)
{
    dd[x]=y;
    if(zs[x]==0)
    {
        return;
    }
    lb(zs[x],y);
    for(int i=head[x];i!=0;i=next[i])
    {
        if(dd[to[i]]==0)
        {
            lb(to[i],to[i]);
        }
    }
}
int qz(int x,int y)
{
    while(dd[x]!=dd[y])
    {
        if(sd[dd[x]]<sd[dd[y]])
        {
            swap(x,y);
        }
        x=f[dd[x]];
    }
    if(sd[x]<sd[y])
    {
        return x;
    }
    else
    {
        return y;
    }
}
int main()
{
    int x,y;
    scanf("%d%d%d",&n,&m,&s);
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    js(s,0,1);
    lb(s,s);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",qz(x,y));
    }
    return 0;
}

然后再学习倍增的lca,专研了一会,就向zx同学强请制教(物理)了

zx奆佬讲的思路很容易理解,但代码要下点功夫(主要是我脑子不好,不像隔壁zx同学秒切).

倍增的代码如下:

#include<bits/stdc++.h>
using namespace std;
int cnt,n,m,s,sd[1000001],f[1000001][31],next[1000001],head[1000001],to[1000001];
inline void add(register int u,register int v)
{
    next[++cnt]=head[u];
    head[u]=cnt;
    to[cnt]=v;
}
void js(int x,int y)
{
    sd[x]=sd[y]+1;
    for(int i=1;(1<<i)<=sd[x];++i)
    {
        f[x][i]=f[f[x][i-1]][i-1];
    } 
    for(int i=head[x];i!=0;i=next[i])
    {
        if(to[i]!=y)
        {
            f[to[i]][0]=x;
            js(to[i],x);
        }
    }
    return;
}
int lca(int x,int y)
{
    if(sd[x]<sd[y])
    {
        swap(x,y);
    }
    for(int i=20;i>=0;i--)
    {
        if(sd[f[x][i]]>=sd[y])
        {
            x=f[x][i];
        }
        if(x==y)
        {
            return x;
        }
    }
    for(int i=20;i>=0;i--)
    {
        if(f[x][i]!=f[y][i])
        {
            x=f[x][i];
            y=f[y][i];
        }
    }
    return f[x][0];
}
int main()
{
    int x,y;
    scanf("%d%d%d",&n,&m,&s);
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    js(s,0);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",lca(x,y));
    }
    return 0;
}

 

下午,写了一些初赛的题与LCA的题

总的来说还不错.

今天又TM是开森的一天呢!

标签:cnt,int,2021.8,北中,head,1000001,next,暑训,sd
来源: https://www.cnblogs.com/zhangpuwen/p/15170936.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有