// 最小瓶颈路 指两点之间所有路径中最大的边最小的路径
//在最小生成树中,最小瓶颈路就是两点之间的最大值;
先给出一个概念,最小生成树一定是最小瓶颈树(注意这里是树),但反过来的话就不一定;
所以,我们可以用最小生成树的知识来解;
在解的时候,我们需要一步一步的将新加进来的点,与原先已经加进来的点之间的最小瓶颈路进行更新;
具体更新方式是:用新加的边,与这个边所带的(点有两个,一个新加的,一个原先就在)原先的点与j的距离进行比较
取最大值,即可;代码中有注释;
所以,我们需要一个操作,来记录这条边原先的点(代码中有注释)
其余的就是最小生成树的操作了
1 #include <bits/stdc++.h>
2 using namespace std;
3 const int MAXN=1000+10;
4 const int INF=0x3f3f3f3f;
5 int n,m,k;
6 int mapp[MAXN][MAXN];
7 int ans[MAXN][MAXN],dis[MAXN],pri[MAXN];
8 bool vis[MAXN];
9 void prim()
10 {
11 memset(vis,false,sizeof(vis));
12 for(int i=1;i<=n;++i){
13 dis[i]=INF;
14 pri[i]=i;
15 }
16 dis[1]=0;
17 for(int i=1;i<=n;++i){
18 int MAXX=INF,v=-1;
19 for(int j=1;j<=n;++j){
20 if(!vis[j]&&dis[j]<MAXX){
21 MAXX=dis[v=j];
22 }
23 }
24 if(v==-1) break;
25 for(int j=1;j<=n;++j)
26 if(vis[j])
27 ans[v][j]=ans[j][v]=max(ans[pri[v]][j],MAXX);
28 //用新加的边,与这个边所带的(点有两个,一个新加的,一个原先就在)
29 //原先的点与j的距离进行比较
30 vis[v]=true;
31 for(int j=1;j<=n;++j){
32 if(!vis[j]&&mapp[v][j]<dis[j]){
33 dis[j]=mapp[v][j];
34 pri[j]=v; //记录这条边的已经在图中的那个端点
35 }
36 }
37 }
38 }
39
40 int main()
41 {
42 scanf("%d%d%d",&n,&m,&k);
43 int x,y,z;
44 memset(mapp,0x3f,sizeof(mapp));
45 memset(ans,0,sizeof(ans));
46 for(int i=0;i<=n;++i) mapp[i][i]=0;
47 for (int i=0;i<m;++i){
48 scanf("%d%d%d",&x,&y,&z);
49 if(mapp[x][y]>z)
50 mapp[x][y]=mapp[y][x]=z; //有重边
51 }
52 prim();
53 while(k--){
54 scanf("%d%d",&x,&y);
55 printf("%d\n",ans[x][y]==0?-1:ans[x][y]);
56 }
57 return 0;
58 }
这代码不是自己写的
这里再贴一个krusal+lca的算法
1 #include<bits/stdc++.h>
2 #define re return
3 #define lowbit(x) (x&(-x))
4 #define dec(i,l,r) for(int i=l;i>=r;--i)
5 #define inc(i,l,r) for(int i=l;i<=r;++i)
6 const int maxn=1005,maxm=200005;
7 using namespace std;
8 template<typename T>inline void rd(T&x)
9 {
10 char c;bool f=0;
11 while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
12 x=c^48;
13 while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
14 if(f)x=-x;
15 }
16
17 int n,m,q,deep[maxn],hd[maxn],fa[maxn],f[maxn][25],dis[maxn][25];
18
19 struct node{
20 int fr,to,nt,val;
21 bool operator<(node x)const
22 {
23 re val<x.val;
24 }
25 }e[maxn<<1],e1[maxm];
26
27 inline int find(int x)
28 {
29 re x==fa[x]?x:fa[x]=find(fa[x]);
30 }
31 inline void dfs(int x,int fa)
32 {
33 deep[x]=deep[fa]+1;
34 for(int i=0;f[f[x][i]][i];++i)
35 {
36 f[x][i+1]=f[f[x][i]][i];
37 dis[x][i+1]=max(dis[x][i],dis[f[x][i]][i]);
38 }
39 for(int i=hd[x];i;i=e[i].nt)
40 {
41 int v=e[i].to;
42 if(v!=fa)
43 {
44 f[v][0]=x;
45 dis[v][0]=e[i].val;
46 dfs(v,x);
47 }
48 }
49 }
50
51 inline int LCA(int x,int y)
52 {
53 int ans=0;
54 if(deep[x]<deep[y])x^=y^=x^=y;
55 dec(i,24,0)
56 if(deep[f[x][i]]>=deep[y])
57 {
58 ans=max(ans,dis[x][i]);
59 x=f[x][i];
60 }
61 if(x==y)re ans;
62
63 dec(i,24,0)
64 if(f[x][i]!=f[y][i])
65 {
66 ans=max(ans,dis[x][i]);
67 ans=max(ans,dis[y][i]);
68 x=f[x][i];
69 y=f[y][i];
70 }
71 re max(ans,max(dis[x][0],dis[y][0]));
72 }
73 int main()
74 {
75
76 int x,y,z;
77 rd(n),rd(m);rd(q);
78 inc(i,1,m){
79 rd(x),rd(y),rd(z);
80 e1[i]=(node){x,y,0,z};
81 }
82 sort(e1+1,e1+m+1);
83 int cnt=0,k=0;
84 inc(i,1,n)fa[i]=i;
85 inc(i,1,m){
86 int x=e1[i].fr,y=e1[i].to,w=e1[i].val;
87 int f1=find(fa[x]),f2=find(fa[y]);
88 if(f1!=f2){
89 e[++k]=(node){x,y,hd[x],w};hd[x]=k;
90 e[++k]=(node){y,x,hd[y],w};hd[y]=k;
91 ++cnt;
92 fa[f1]=f2;
93 if(cnt==n-1)break;
94 }
95 }
96 inc(i,1,n)
97 if(!deep[i]) dfs(i,0);
98 int s,t;
99 inc(i,1,q){
100 rd(s),rd(t);
101 if(i==27) x=1;
102 if(find(s)!=find(t))printf("-1\n");
103 else printf("%d\n",LCA(s,t));
104 }
105 re 0;
106 }