和洛谷1967一样,只不过是求一个最小生成树,然后和上一道题一样,先构建新图,然后lca求到祖先距离的最大值
代码
//By AcerMo
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=700500;
struct edge
{
int from,to,cost;
bool friend operator < (edge a,edge b)
{
return a.cost>b.cost;
}
}now;//初始建图
priority_queue<edge>q;
struct map
{
int to,cost;
}_233;//新图
vector<map>v[M];
int n,m,que;
int vis[M/4],deep[M/4],pt[M/4][22];
int fa[M/4],size[M/4],fatt[M/4][22];
int find(int x)
{
if (x!=fa[x]) return fa[x]=find(fa[x]);
return x;
}
void unionn(int a,int b)
{
if (size[a]<=size[b]) size[b]+=size[a],fa[a]=b;
else size[a]+=size[b],fa[b]=a;
return ;
}//加入了按秩合并以及路径压缩
void constt()
{
for (int i=0;i<=n;i++)
size[i]=1,fa[i]=i,fatt[i][0]=i,deep[i]=1;
return ;
}//初始化每个点的信息
void kru()
{
int cnt=1;constt();
while (q.size()&&cnt<n)
{
now=q.top();q.pop();
int r1=find(now.from);
int r2=find(now.to);
if (r1!=r2)
{
unionn(r1,r2),cnt++;
_233.to=now.to;_233.cost=now.cost;v[now.from].push_back(_233);
_233.to=now.from;_233.cost=now.cost;v[now.to].push_back(_233);
}//注意加入新图的是原点而不是祖先
}
return ;
}//最大生成树及构建新图
void getlca(int x)
{
vis[x]=1;
for (int i=0;i<v[x].size();i++)
{
int go=v[x][i].to;
if (vis[go]) continue;
deep[go]=deep[x]+1;
fatt[go][0]=x;
pt[go][0]=v[x][i].cost;
getlca(go);
}
return ;
}//构建lca祖先关系
void getminpath()
{
for (int i=1;i<=20;i++)
for (int k=1;k<=n;k++)
{
fatt[k][i]=fatt[fatt[k][i-1]][i-1];
pt[k][i]=max(pt[k][i-1],pt[fatt[k][i-1]][i-1]);
}
return ;
}//预处理每个点到祖先的距离
int lca(int x,int y)
{
int ans=0;
if (deep[x]>deep[y]) swap(x,y);
for (int i=20;i>=0;i--)
if (deep[fatt[y][i]]>=deep[x])
ans=max(ans,pt[y][i]),y=fatt[y][i];
if (x==y) return ans;
for (int i=20;i>=0;i--)
if (fatt[x][i]!=fatt[y][i])
ans=max(ans,max(pt[x][i],pt[y][i])),
x=fatt[x][i],y=fatt[y][i];
ans=max(ans,max(pt[x][0],pt[y][0]));
return ans;
}//lca求解
int main()
{
scanf("%d%d%d",&n,&m,&que);
for (int i=1;i<=m;i++)
scanf("%d%d%d",&now.from,&now.to,&now.cost),q.push(now);
kru();
for (int i=1;i<=n;i++)
if (!vis[i]) getlca(i);
getminpath();
while (que--)
{
int x,y;
scanf("%d%d",&x,&y);
int ans=lca(x,y);
cout<<ans<<endl;
}
return 0;
}