最小瓶颈路
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 }
以上是关于最小瓶颈路的主要内容,如果未能解决你的问题,请参考以下文章