#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
struct Edge
{
int u,v,limit;
inline void Read()
{
scanf("%d%d%d",&u,&v,&limit);
}
}Sed[50004];
int son[10004];
struct Edge2
{
int link,next,limit;
}ed[50004];
int Ecnt;
inline void Add(int u,int v,int l)
{
ed[++Ecnt].link=v,ed[Ecnt].limit=l,ed[Ecnt].next=son[u];
son[u]=Ecnt;
}
int f[10004],h[10004],d[10004],fa[10004],ll[10004];
int getf(int x)
{
if (f[x]==x) return x;
return f[x]=getf(f[x]);
}
void Get_Dep(int x,int dep)
{
d[x]=dep;
for (int i=son[x];i;i=ed[i].next) Get_Dep(ed[i].link,dep+1),fa[ed[i].link]=x,ll[ed[i].link]=ed[i].limit;
}
const int INF=~0U>>4;
int Get_Ans(int u,int v) //LCA
{
int x=u,y=v,ans=INF;
while (x!=y)
{
if (d[x]<d[y]) y=fa[y];
else if (d[x]>d[y]) x=fa[x];
else x=fa[x],y=fa[y];
}
while (u!=x) ans=min(ans,ll[u]),u=fa[u];
while (v!=y) ans=min(ans,ll[v]),v=fa[v];
return ans;
}
inline bool cmp(const Edge& A,const Edge& B)
{
return A.limit>B.limit;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
Sed[i].Read();
for (int i=1;i<=n;i++)//预处理
h[i]=0,f[i]=i;
sort(Sed+1,Sed+m+1,cmp);
for (int i=1;i<=m;i++) //构树
{
Edge x=Sed[i];
int u=getf(x.u),v=getf(x.v);
if (u==v) continue;
if (h[u]>h[v]) Add(u,v,x.limit),f[f[v]]=u;
else if (h[u]<h[v]) Add(v,u,x.limit),f[f[u]]=v;
else Add(u,v,x.limit),h[u]++,f[f[v]]=u;
}
for (int i=1;i<=n;i++)
if (f[i]==i) Get_Dep(i,1);
int q;
scanf("%d",&q);
for (int i=1,u,v;i<=q;i++)
{
scanf("%d%d",&u,&v);
if (getf(u)!=getf(v))
{
puts("-1");
continue;
}
printf("%d\n",Get_Ans(u,v));
}
return 0;
}
【P1843】货车运输(最大生成树+LCA)
最新推荐文章于 2021-08-13 10:51:14 发布