最小瓶颈路

Posted pangbi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最小瓶颈路相关的知识,希望对你有一定的参考价值。

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

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

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

具体更新方式是:用新加的边,与这个边所带的(点有两个,一个新加的,一个原先就在)原先的点与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
",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
");
103         else printf("%d
",LCA(s,t));
104     }
105     re 0;
106 }

 

以上是关于最小瓶颈路的主要内容,如果未能解决你的问题,请参考以下文章

最小瓶颈路

最小瓶颈路

最小瓶颈路 Uva 534 Frogger

poj-2253(最小瓶颈路问题)

uva 10457(最小瓶颈路)

最小瓶颈路