首页 > 其他 > 详细

最小瓶颈路

时间:2019-11-04 19:42:54      阅读:79      评论:0      收藏:0      [点我收藏+]

先给出一个概念,最小生成树一定是最小瓶颈树(注意这里是树),但反过来的话就不一定;

所以,我们可以用最小生成树的知识来解;

在解的时候,我们需要一步一步的将新加进来的点,与原先已经加进来的点之间的最小瓶颈路进行更新;

具体更新方式是:用新加的边,与这个边所带的(点有两个,一个新加的,一个原先就在)原先的点与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 }

这代码不是自己写的

最小瓶颈路

原文:https://www.cnblogs.com/pangbi/p/11794041.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!