P2245 星际导航
最小瓶颈路:在一张无向图上,对于点 u、v 找出从 u、v 的一条简单路径,使得路径上行所有边中最大值最小。
因为是求最小数,因此必须要去无向图的最小生成树,然后求LCA,可以用与倍增相似的方法求解
注意:这道题要判断不连通的情况
#include <bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
//#define int long long
//#define double long double
//#define double long long
#define re int
//#define void inline void
#define eps 1e-8
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
#define pi acos(-1.0)
#define pb push_back
#define mk make_pair
#define P pair < int , int >
using namespace std;
const int mod=1e9+7;
//const int inf=1e18;
const int M=1e8;
const int N=8e5+5;//??????.???? 4e8int n,xx,k;
struct node
{
int ver,edge,next;
}e[N];
struct nc
{
int x,y,z;
}a[N];
int tot,head[N];
int fa[N];
int n,m,t;
int f[N][65],dis[N][65],dep[N];
int get(int x)
{
if(fa[x]==x) return x;
return fa[x]=get(fa[x]);
}
bool cmp(nc i,nc j)
{
return i.z<j.z;
}
void add(int x,int y,int z)
{
e[++tot].ver=y;
e[tot].edge=z;
e[tot].next=head[x];
head[x]=tot;
}
void addedge(int x,int y,int z)
{
add(x,y,z);add(y,x,z);
}
void bfs(int s)
{
queue < int > q;
q.push(s);dep[s]=1;
while(q.size())
{
int x=q.front();q.pop();
for(re i=head[x];i;i=e[i].next)
{
int y=e[i].ver;
int z=e[i].edge;
if(dep[y]) continue;
q.push(y);
dep[y]=dep[x]+1;
f[y][0]=x;
dis[y][0]=z;
for(re j=1;j<=t;j++) f[y][j]=f[f[y][j-1]][j-1],dis[y][j]=max(dis[y][j-1],dis[f[y][j-1]][j-1]);
}
}
}
void dfs(int x,int pre,int last)
{
dep[x]=dep[pre]+1;
f[x][0]=pre,dis[x][0]=last;
for(re j=1;j<=t;j++) f[x][j]=f[f[x][j-1]][j-1],dis[x][j]=max(dis[x][j-1],dis[f[x][j-1]][j-1]);
for(re i=head[x];i;i=e[i].next)
{
int y=e[i].ver;
int z=e[i].edge;
if(y==pre) continue;
dfs(y,x,z);
}
}
int lca(int x,int y)
{
int ans=0;
if(dep[x]>dep[y]) swap(x,y);
for(re i=t;i>=0;i--) if(dep[f[y][i]]>=dep[x]) ans=max(ans,dis[y][i]),y=f[y][i];
if(x==y) return ans;
for(re i=t;i>=0;i--) if(f[x][i]!=f[y][i])
ans=max(ans,max(dis[x][i],dis[y][i])),x=f[x][i],y=f[y][i];
ans=max(ans,max(dis[x][0],dis[y][0]));
return ans;
}
void solve()
{
cin>>n>>m;
t=(int)(log(n)/log(2))+1;
for(re i=1;i<=n;i++) fa[i]=i;
for(re i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
sort(a+1,a+m+1,cmp);
for(re i=1;i<=m;i++)
{
int xx=get(a[i].x);
int yy=get(a[i].y);
if(xx==yy) continue;
fa[xx]=yy;
addedge(a[i].x,a[i].y,a[i].z);
}
// for(re i=1;i<=n;i++) if(!dep[i]) dfs(i,0,0);
for(re i=1;i<=n;i++) if(!dep[i]) bfs(i);
cin>>m;
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
if(get(x)!=get(y)) puts("impossible");
else printf("%d\n",lca(x,y));
}
}
signed main()
{
int T=1;
// cin>>T;
for(int index=1;index<=T;index++)
{
solve();
// puts("");
}
return 0;
}
/*
abcRefRc
*/