20200923 货车运输

题面
因为有一点忘了算法,然后想借助题来复习一下,所以有一些算法会复习的比较详细。
首先可以看到,这是一个先以(1)为根建一颗最大生成树,再用倍增求(LCA)

并查集

具体来说现将一个集合的中所有元素进行个体分离,然后根据关系进行集合,最后判断几个点是否有关系只需判断是否在一个集合中即可。

int find(int t)
{
    if(f[t]==t)
    {
        return t;
    }
    else
    {
        return f[t]=find(f[t]);
    }
}

最大生成树


我们将对边权进行排序,边权大的将被优先选择。选边时,若这一条边的两个顶点不在一个集合内就将二者合并,这里就用到了并查集的思想,并将加入的边的条数增加(1),然后建边,当已经选了(n-1)条边时就跳出循环,因为(n)个点需要(n-1)条边才能够两两互达且为树。
下面就是该图的最大生成树:

倍增

1号点第(i)次跳跃跳到的格子为(1+2^i)。那么如果我们设(g[x][i])表示的是(x)号点跳第(i)次的位置的话,那么(g[x][i]=g[g[x][i−1]][i−1]),此处感觉十分的好理解。显然,我们可以先从(x)点跳到离(y)点最近的且不超过(y)点的那个点。然后再从该点起步,继续跳下去,直到跳到(y)点为止。这种算法的时间复杂度为(O(nlog2n))

LCA

最近一直在刷LCA的题,然后就不在这里展开讲了。

int lca(int x,int y)
{
    int ans=inf;
    if(deep[x]<deep[y])
    {
        int t=x;
        x=y;
        y=t;
    }
    for(int i=20;i>=0;i--)
    {
        if(deep[p[x][i]]>=deep[y])
        {
            ans=min(ans,w[x][i]);
            x=p[x][i];
        }
    }
    if(x==y)
    {
        return ans;
    }
    for(int i=20;i>=0;i--)
    {
        if(p[x][i]!=p[y][i])
        {
            ans=min(ans,min(w[x][i],w[y][i]));
            x=p[x][i];
            y=p[y][i];
            
        }
    }
    ans=min(ans,min(w[x][0],w[y][0]));
    return ans;
}

注意了,当有(2)棵树或多棵树时,要将没有深度的点(即不与点(1)在同一棵树内的点)的深度改为(1),如果不改的话就会输出(0)哦。

下面我将把代码中的一些重要的部分拆开来解释,方便大家理解。

代码段还请见(lca())部分。

因为我们规定了是(x)去找(y),所以当(y)(x)深时就要交换(x)(y)。调换(x)(y)并不会影响答案,因为(lca(x,y)=lca(y,x))

if(deep[x]<deep[y])
{
    int t=x;
    x=y;
    y=t;
}

这里是让(x)和跳到和(y)同一层,并在路上记录最小值, 若(y)就是(x)的公共祖先(见下图)就直接返回答案即可。否则就让(x)(y)一起跳到它们的最近公共祖先的前一步的那个点去,最后再跳一步(即跳到(x)(y)的最近公共祖先那里去)。最后再返回所经过的路径中的最小值即可。注意赋值的顺序不要反了。

for(int i=20;i>=0;i--)
{
    if(deep[p[x][i]]>=deep[y])
    {
        ans=min(ans,w[x][i]);
        x=p[x][i];
    }
}
    if(x==y)
    {
        return ans;
    }
    for(int i=20;i>=0;i--)
    {
        if(p[x][i]!=p[y][i])
        {
            ans=min(ans,min(w[x][i],w[y][i]));
            x=p[x][i];
            y=p[y][i];
        }
    }
    ans=min(ans,min(w[x][0],w[y][0]));
    return ans;
原文地址:https://www.cnblogs.com/scy-fisheep/p/13716108.html