关于倍增求树上简单路径中的最小边权
  • 板块灌水区
  • 楼主sycqwq
  • 当前回复17
  • 已保存回复17
  • 发布时间2021/10/9 22:51
  • 上次更新2023/11/4 04:13:35
查看原帖
关于倍增求树上简单路径中的最小边权
151647
sycqwq楼主2021/10/9 22:51

就是倍增求lca,然后再求lca路径上的最小值

蒟蒻有点不太清楚

就是代码中的(会的应该都知道代码吧)mi[i][j]代表的是什么

代码:

#include<bits/stdc++.h>
using namespace std;
int fa[10005];
    int n,m,q;
int getfa(int x)
{
    // cout<<x<<endl;
    if(fa[x]==x)
        return x;
    return fa[x]=getfa(fa[x]);
}
struct node
{
    int u,v,w,nxt;
}e[100005],a[100005];
int tot,head[100005];
int add(int u,int v,int w)
{
    a[++tot].v=v;
    a[tot].nxt=head[u];
    a[tot].w=w;
    head[u]=tot;
}
int cmp(node s1,node s2)
{
    return s1.w>s2.w;
}
void kruskal()
{
    for(int i=1;i<=m;i++)
    {
        int x=getfa(e[i].u),v=getfa(e[i].v);
        if(x!=v)
        {
            fa[x]=v;
            add(e[i].u,e[i].v,e[i].w);
            add(e[i].v,e[i].u,e[i].w);
        }
    }
}
int d[100005],f[10005][25],mi[10005][25];
int dfs(int x,int fa)
{
    d[x]=d[fa]+1;
    for(int i=head[x];i;i=a[x].nxt)
    {
        int v=a[i].v;
        if(v==fa)
            continue;
        f[v][0]=x;
        mi[v][0]=a[i].w;
        dfs(v,x);
    }
}
int lca(int x,int y)
{
    if(d[y]<d[x])
        swap(x,y);
        int s=INT_MAX;
    for(int i=20;i>=0;i--)
    {
        if(d[f[y][i]]>=d[x])
        {
            s=min(s,mi[y][i]);
            y=f[y][i];
        }
    }
    if(x==y)
        return s;
    for(int i=20;i>=0;i--)
    {
        if(f[x][i]!=f[y][i])
        {
            s=min(s,min(mi[x][i],mi[y][i]));
            x=f[x][i];
            y=f[x][i];
        }
    }
    return min(s,mi[x][0]);
}
int main()
{   
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        fa[i]=i;
    for(int i=1;i<=m;i++)
    {
        cin>>e[i].u>>e[i].v>>e[i].w;
    }
    sort(e+1,e+m+1,cmp);
    kruskal();
    for(int i=1;i<=n;i++)
    {
        if(fa[i]==i)
        {
            dfs(i,0);
        }
    }
    for(int i=1;i<=20;i++)
        for(int j=1;j<=n;j++)
        {
            f[j][i]=f[f[j][i-1]][i-1];
            mi[j][i]=mi[mi[j][i-1]][i-1];
        }
    
    cin>>q;
    for(int i=1;i<=q;i++)
    {
        int x,y;
        cin>>x>>y;
        if(getfa(x)!=getfa(y))
        {
            cout<<-1<<endl;
            continue;
        }
        cout<<lca(x,y)<<endl;
    }
    return 0;
}
2021/10/9 22:51
加载中...