这题本来想用Prim来求最小瓶颈路的,但是n太大了,所以用LCA倍增来求。
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=50000+5;
const int maxm=100000+5;
const int logmax=20;
const int inf=1000000000;
int fa[maxn],cost[maxn],dep[maxn],anc[maxn][logmax],maxcost[maxn][logmax];
int n,m;
struct edge{
int u,v,w;
edge(int u=0,int v=0,int w=0): u(u),v(v),w(w) {}
bool operator < (const edge &rhs) const {
return w<rhs.w;
}
}e[maxm];
vector<int> G[maxn];
vector<vector<edge> > nG(maxn);
int pa[maxn];
int vis[maxn];
int findset(int x) {return pa[x]==x?x:findset(pa[x]);}
void kruskal(int c)
{
sort(e,e+c);
for(int i=0;i<c;i++)
{
int root1=findset(e[i].u);
int root2=findset(e[i].v);
if(root1==root2) continue;
pa[root2]=root1;
nG[e[i].u].push_back(edge(e[i].u,e[i].v,e[i].w));
nG[e[i].v].push_back(edge(e[i].v,e[i].u,e[i].w));
}
}
void dfs(int u,int f,int c,int d)
{
vis[u]=1;
fa[u]=f;cost[u]=c;dep[u]=d;
for(int i=0;i<nG[u].size();i++)
{
int v=nG[u][i].v;
int c=nG[u][i].w;
if(vis[v]) continue;
dfs(v,u,c,d+1);
}
}
void preprocess()
{
for(int i=1;i<=n;i++){
anc[i][0]=fa[i];maxcost[i][0]=cost[i];
for(int j=1;(1<<j)<=n;j++){
anc[i][j]=-1;maxcost[i][j]=0;
}
}
for(int j=1;(1<<j)<=n;j++)
{
for(int i=1;i<=n;i++)
{
if(anc[i][j-1]!=-1)
{
int a=anc[i][j-1];
anc[i][j]=anc[a][j-1];
maxcost[i][j]=max(maxcost[i][j-1],maxcost[a][j-1]);
}
}
}
}
int query(int p,int q)
{
int log;
if(dep[p]<dep[q]) swap(p,q);
for(log=1;(1<<log)<=dep[p];log++) ;log--;
int ans=-inf;
for(int i=log;i>=0;i--) if(dep[p]-(1<<i)>=dep[q]) {ans=max(ans,maxcost[p][i]);p=anc[p][i];}
if(p==q) return ans;
for(int i=log;i>=0;i--){
if(anc[p][i]!=-1&&anc[p][i]!=anc[q][i]){
ans=max(ans,maxcost[p][i]);p=anc[p][i];
ans=max(ans,maxcost[q][i]);q=anc[q][i];
}
}
ans=max(ans,cost[p]);
ans=max(ans,cost[q]);
return ans;
}
int main()
{
int kase=0;
while(~scanf("%d%d",&n,&m))
{
int c=0;
for(int i=1;i<=n;i++) {G[i].clear();nG[i].clear();pa[i]=i;}
for(int i=1;i<=m;i++) {
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
G[x].push_back(y);
G[y].push_back(x);
e[c].u=x;e[c].v=y;e[c].w=w;c++;
}
kruskal(c);
memset(vis,0,sizeof(vis));
dfs(1,-1,0,0);
preprocess();
if(kase++) printf("\n");
int q;
scanf("%d",&q);
while(q--)
{
int u,v;
scanf("%d%d",&u,&v);
printf("%d\n",query(u,v));
}
}
return 0;
}