解题思路:先用最小生成树的方法生成一个最大生成树,在使用倍增做lca的同时将最小值找出来(类似于st表,st也是用倍增,相当于使用倍增同时搞出lca与st表)
注意事项:读入与输出较大,使用较快的输入输出,不然会超时
参考代码:
#include<bits/stdc++.h>
using namespace std;
struct node
{
int from;
int to;
int w;
int next;
}mp[1000005];
vector<node>v;
int head[100005],cnt=0;
void add(int a,int b,int c)
{
mp[++cnt].to=b;
mp[cnt].next=head[a];
mp[cnt].w=c;
head[a]=cnt;
}
bool cmp(node a,node b)
{
return a.w>b.w;
}
int f[1000005];
int fand(int x)
{
if(f[x]!=x)
{
return f[x]=fand(f[x]);
}
return x;
}
void meare(node a)
{
int x,y;
x=fand(a.from);
y=fand(a.to);
if(x!=y)
{
add(a.from,a.to,a.w);
add(a.to,a.from,a.w);
f[y]=x;
}
}
int deep[1000005];
int st[1000005][25];
int stmax[1000005][25];
void dfs(int u,int fa,int w)
{
deep[u]=deep[fa]+1;
st[u][0]=fa;
stmax[u][0]=w;
for(int i=1;i<=19;i++)
{
st[u][i]=st[st[u][i-1]][i-1];
stmax[u][i]=min(stmax[u][i-1],stmax[st[u][i-1]][i-1]);
}
for(int i=head[u];i;i=mp[i].next)
{
int v;
v=mp[i].to;
if(v!=fa)
{
dfs(v,u,mp[i].w);
}
}
}
int lca(int a,int b)
{
int ans=1E9;
if(deep[a]<deep[b])swap(a,b);
for(int i=19;i>=0;i--)
{
if(deep[st[a][i]]>=deep[b])
{
ans=min(ans,stmax[a][i]);
a=st[a][i];
}
}
if(a==b)return ans;
for(int i=19;i>=0;i--)
{
if(st[a][i]!=st[b][i])
{
ans=min(ans,stmax[a][i]);
ans=min(ans,stmax[b][i]);
a=st[a][i];
b=st[b][i];
}
}
ans=min(ans,stmax[a][0]);
ans=min(ans,stmax[b][0]);
return ans;
}
int main()
{
int n,m,q;
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++)
{
f[i]=i;
}
for(int i=1;i<=m;i++)
{
node a;
scanf("%d%d%d",&a.from,&a.to,&a.w);
v.push_back(a);
}
sort(v.begin(),v.end(),cmp);
for(int i=0;i<v.size();i++)
{
meare(v[i]);
}
for(int i=1;i<=n;i++)
{
if(deep[i]==0)dfs(i,0,0);
}
while(q--)
{
int x,y;
scanf("%d%d",&x,&y);
int ans;
ans=lca(x,y);
if(fand(x)!=fand(y))
{
printf("-1\n");
}
else
{
printf("%d\n",ans);
}
}
return 0;
}0.0分
2 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复