码迷,mamicode.com
首页 > 其他好文 > 详细

最小瓶颈生成树

时间:2018-10-04 09:25:53      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:roc   check   优化   sort   nbsp   define   sub   break   代码   

所谓最小瓶颈生成树....就是使得生成树树上最大边权值最小。

这里主要介绍一种期望O(M)(线性)的求法,其实主要就是二分,具体思路如下:

类比找第k大值的方法,首先随机一个边权w。

然后将不超过这个边权的边加入,遍历这张图。

如果图连通,那么瓶颈不超过w,于是只需考虑边权不超过w的边。

否则将这些连通点缩起来,考虑边权大于w的边。

每次将问题的规模缩小至一半。

期望时间复杂度O(m)。

相关例题有两道:

A.Hangar Hurdles (CERC 16)

有一个n*n的网格图,上面有些格子可行,有些格子是障碍。 有Q个询问,想把一个正方形箱子从(r1,c1)推到(r2,c2),问箱子最大的大小。(起点终点是正方形箱子的中点) N<=1000 Q<=300000

B.洪蛤吨有一个宽度为L的管道,我们可以视其为一条y=L的直线与X轴所夹的部分。

(所以这根管道的长度可以视为正无穷)

这个管道中有个N个障碍点,第i个障碍点的坐标为(Xi,Yi)

已知有一个球体,能在不碰到障碍点的前提下,从管道的最左端走到最右端。(即从管道内横坐标负无穷的地方走到横坐标正无穷的地方)。

求这个球体的直径最大是多少。为了避免精度误差,请输出答案保留三位小数的结果。

两题有异曲同工之妙a...(/滑稽,思路差不多...)都可以用最小瓶颈树实现复杂度最小

下面上一下t2的代码:(没有用最小瓶颈树优化,逃)

 1 #include<bits/stdc++.h>
 2 #define maxn 505
 3 using namespace std;
 4 struct eage{
 5     int u,v;
 6     double dist;
 7 }e[maxn*maxn/2+maxn*2];
 8 bool cmp(eage a,eage b){
 9     return a.dist<b.dist;
10 }
11 double dis(int x1,int y1,int x2,int y2){
12     return sqrt(1.0*(x1-x2)*(x1-x2)+1.0*(y1-y2)*(y1-y2)); 
13 }
14 int fa[maxn];
15 int find(int x){
16     if(fa[x]==x) return x;
17     int root=find(fa[x]);
18     fa[x]=root;
19     return root;
20 }
21 void link(int x,int y){
22     int fx=find(x),fy=find(y);
23     if(fx!=fy){
24         fa[fx]=fy;
25     } 
26 }
27 bool check(int x,int y){
28     int fx=find(x),fy=find(y);
29     if(fx!=fy) return false;
30     return true;
31 }
32 int l,n;
33 struct node{
34     int x,y;
35 }nd[maxn];
36 void init(){
37     int pos=0;
38     scanf("%d%d",&n,&l);
39     for(int i=1;i<=n+2;i++) fa[i]=i;//n+1是上,n+2是下 
40     for(int i=1;i<=n;i++){
41         scanf("%d%d",&nd[i].x,&nd[i].y);
42     }
43     for(int i=1;i<=n;i++){
44         e[++pos]=(eage){i,n+1,l-nd[i].y};
45         e[++pos]=(eage){i,n+2,nd[i].y};
46     for(int j=i+1;j<=n;j++){
47         e[++pos]=(eage){i,j,dis(nd[i].x,nd[i].y,nd[j].x,nd[j].y)};
48     }
49     }
50     int cnt=0;
51     sort(e+1,e+pos+1,cmp);
52     for(int i=1;i<=pos;i++){
53         int u=e[i].u,v=e[i].v;
54         if(check(u,v)) continue;
55         link(u,v);
56         cnt++;
57         if(find(n+1)==find(n+2)){//只要上底和下底连接了就行 这样才能保证极大值可以通过
58                                  //如果后面更大,那这里是过不了的 
59             printf("%.3f",e[i].dist);
60             break;
61         }
62     }
63 }
64 int main(){
65     init();
66     
67     return 0;
68 }

 

最小瓶颈生成树

标签:roc   check   优化   sort   nbsp   define   sub   break   代码   

原文地址:https://www.cnblogs.com/degage/p/9740739.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!