就是倍增求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;
}