• hdu


    传送门

    (这次的英文题面要比上一个容易看多了)

    (英语蒟蒻的卑微)

    又是一个很裸的LCA题

    (显然,这次不太容易打暴力咧)

    (但听说还是有大佬用dfs直接a掉了)

    正好

    趁这个机会复习一下LCA

    这里用的是倍增lca

    的思想(一不小心是会写tle的吧)

    (也有可能是因为我太弱了才t掉的)

    我才不会说我有一次卑微了

    一开始看PPT

    以为自己明白了

    结果发现

    有一点点问题

    由于本题中这个树是题里给的

    所以节点的编号不可以简简单单认为是从上到下从左到右顺序排列的

    (但其实这部算什么大问题啊qwq)

    (还是我太弱了)

    长记性了的我这次记住了要加' '

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define maxn 40000
    using namespace std;
    
    struct EDGE
    {
        int nxt,to,v;
    }edge[maxn*2+5];
    
    int T,n,root,cnt,m;
    int head[maxn+5],dep[maxn+5],dis[maxn+5];
    int f[maxn+5][25];
    bool vis[maxn+5];
    
    void add(int x,int y,int z)
    {
        edge[++cnt].to=y;
        edge[cnt].v=z;
        edge[cnt].nxt=head[x];
        head[x]=cnt;
    }
    
    void dfs(int u,int fa)
    {
        dep[u]=dep[fa]+1;
        for(int i=0; i<=22; i++)
        {
            f[u][i+1]=f[f[u][i]][i];
        }
        for(int i=head[u]; i; i=edge[i].nxt)
        {
            if(edge[i].to==fa)
            {
                continue;
            }
            dis[edge[i].to]=dis[u]+edge[i].v;
            f[edge[i].to][0]=u;
            dfs(edge[i].to,u);
        }
    }
    
    int LCA(int x,int y)
    {
        if(dep[x]<dep[y])
        {
            swap(x,y);
        }
        for(int i=22; i>=0; i--)
        {
            if(dep[f[x][i]]>=dep[y])
            {
                x=f[x][i];
            }
            if(x==y)
            {
                return x;
            }
        }
        for(int i=22; i>=0; i--)
        {
            if(f[x][i]!=f[y][i])
            {
                x=f[x][i];
                y=f[y][i];
            }
        }
        return f[x][0];
    }
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            memset(vis,0,sizeof(vis));
            memset(edge,0,sizeof(edge));
            memset(f,0,sizeof(f));
            memset(dep,0,sizeof(dep));
            memset(head,0,sizeof(head));
            memset(dis,0,sizeof(dis));
            cnt=0;
            scanf("%d%d",&n,&m);
            for(int i=1; i<=n-1; i++)
            {
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                vis[y]=1;
                add(x,y,z);
                add(y,x,z);
            }
            for(int i=1; i<=n; i++)
            {
                if(vis[i]==0)
                {
                    root=i;
                    break;
                }
            }
            dfs(root,0);
            for(int i=1; i<=m; i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                printf("%d
    ",dis[a]+dis[b]-2*dis[LCA(a,b)]);
            }
        }
        return 0;
    }
  • 相关阅读:
    oo第三单元学习总结
    oo第二单元学习总结
    OO第四单元UML作业总结兼OO课程总结
    OO第三单元JML作业总结
    OO第二单元电梯作业总结
    OO第一单元总结
    OOUnit4Summary
    OOUnit3Summary
    OOUnit2Summary
    OOUnit1Summary
  • 原文地址:https://www.cnblogs.com/darlingroot/p/10580785.html
Copyright © 2020-2023  润新知