题意:
求最多最短路径路径的最大权值中的最小值,明显 我们可以建立一颗最大的生成树, 然后在这颗生成树里面求 L C A LCA LCA中的最小值就好了
树上倍增的方法求 L C A LCA LCA 当然也可以直接树剖求
AC代码
#include <bits/stdc++.h>
using namespace std;
#define cpp_io() {ios::sync_with_stdio(false); cin.tie(NULL);}
#define rep(i,a,n) for (int i=a;i<n;i++)
#define repp(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define CLR(a,b) memset(a,(b),sizeof(a))
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ls o<<1
#define rs o<<1|1
typedef long long ll;
typedef vector<int> VI;
const int MAXN = (int)2e5+10;
const int INF = 0x3f3f3f3f;
const int mod = (int)1e9+7;
void F() {
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
}
struct node {
int x,y,z;
}p[MAXN];
struct edge {
int v,c;
edge(int _v=0,int _c=0):v(_v),c(_c){}
};
vector<edge> E[MAXN];
int par[MAXN];
bool in[MAXN];
int f[MAXN][30],w[MAXN][30],dep[MAXN];
int n,m;
void init() {
repp(i,0,MAXN) par[i]=i;
}
bool cmp(node a,node b) {
return a.z>b.z;
}
int find(int x) {
if(par[x]==x) return par[x];
return par[x]=find(par[x]);
}
void unite(int x,int y) {
x=find(x);
y=find(y);
if(x!=y) par[x]=y;
}
void kruskal() {
init();
sort(p+1,p+1+m,cmp);
int k=0;
repp(i,1,m){
if(find(p[i].x)!=find(p[i].y)) {
unite(p[i].x,p[i].y);
E[p[i].x].pb(edge(p[i].y,p[i].z));
E[p[i].y].pb(edge(p[i].x,p[i].z));
k++;
}
if(k==n-1) break;
}
}
void dfs(int u,int fa,int d) {
in[u]=true;
f[u][0]=fa;
dep[u]=d;
rep(i,0,SZ(E[u])){
int v=E[u][i].v;
if(in[v]) continue;
w[v][0]=E[u][i].c;
dfs(v,u,d+1);
}
}
void ycl() {
repp(i,1,n){
if(!in[i]) dfs(i,0,1);
}
repp(i,1,20){
repp(j,1,n){
f[j][i]=f[f[j][i-1]][i-1];
w[j][i]=min(w[j][i-1],w[f[j][i-1]][i-1]);
}
}
}
int lca(int u,int v) {
if(dep[u]<dep[v])swap(u,v);
int ans=INF;
per(i,0,21){
if(dep[f[u][i]]>=dep[v]){
ans=min(ans,w[u][i]);
u=f[u][i];
}
}
if(u==v) return ans;
per(i,0,21){
if(f[u][i]!=f[v][i]){
ans=min(ans,min(w[u][i],w[v][i]));
u=f[u][i],v=f[v][i];
}
}
ans=min(ans,min(w[u][0],w[v][0]));
return ans;
}
int main(int argc, char const *argv[])
{
F();
cpp_io();
cin>>n>>m;
repp(i,1,m) cin>>p[i].x>>p[i].y>>p[i].z;
kruskal();
ycl();
int q; cin>>q;
while(q--){
int u,v;
cin>>u>>v;
if(find(u)!=find(v))
cout<<-1<<endl;
else
cout<<lca(u,v)<<endl;
}
return 0;
}