码迷,mamicode.com
首页 > Web开发 > 详细

BZOJ3732 Network

时间:2016-05-07 15:00:11      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:

题意:给定一个无向图,然后求两点之间的路径中权值最大的边的最小值

 

正解:最小生成树+倍增lca

 

望着这道题10分钟之后感觉做不到一眼秒题,老老实实画图,结果发现我真是太弱了,居然没有发现满足题意的条件竟然是最小生成树的性质。。。

显然先构出最小生成树,其他的边是没有用的,可以删掉。

构出最小生成树之后,就考虑两点间的路径上的最大值。

可以在求lca的时候顺便维护一下就可以了。

我开始打了一个树链剖分+线段树,然而上午脑袋不是很清白,而且鬼畜的BZOJ,居然迷之RE了两次。

好吧,被迫改用倍增,然后就过了,并不知道为什么树链剖分哪里打萎了。

(这道题其实就是NOIP2013的原题货车运输的改版的好吗,几乎一模一样)

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<algorithm>
  7 #include<vector>
  8 #include<queue>
  9 #include<string>
 10 #ifdef WIN32   
 11 #define OT "%I64d"
 12 #else
 13 #define OT "%lld"
 14 #endif
 15 using namespace std;
 16 typedef long long LL;
 17 int n,m;
 18 int u[200011],to[200011],w[200011];
 19 int first[200011],next[200011],u1[200011],to1[200011],ww[200011];
 20 int father[200011],height[200011];
 21 int f[100011][16],quan[100011][16];
 22 
 23 inline int getint(){
 24     int q=0,w=0;
 25     char c=getchar();
 26     while(c!=- && ( c<0 || c>9 ) ) c=getchar();
 27     if(c==-) q=1,c=getchar();
 28     while(c>=0 && c<=9) w=w*10+c-0,c=getchar();
 29     return q?-w:w;    
 30 }
 31 
 32 inline void qsort(int l,int r)
 33 {
 34       int i=l,j=r;
 35       int mid=w[(i+j)/2],p;
 36       do
 37       {
 38          while(w[i]<mid)i++;
 39          while(w[j]>mid)j--;
 40          if(i<=j)
 41          {
 42              p=w[i];w[i]=w[j];w[j]=p;  
 43              p=u[i];u[i]=u[j];u[j]=p;  
 44              p=to[i];to[i]=to[j];to[j]=p;    
 45              i++;
 46              j--;   
 47          }    
 48       }while(i<=j);  
 49       if(i<r)qsort(i,r);
 50       if(l<j)qsort(l,j);
 51 }
 52 
 53 inline int find(int x){
 54       if(father[x]!=x) father[x]=find(father[x]);
 55       return father[x];  
 56 }
 57 
 58 inline void hebing(int x,int y){
 59        father[y]=x; 
 60 }
 61 
 62 inline void dfs(int x,int deep){
 63      height[x]=deep;
 64      for(int i=1;i<=15;i++){
 65            f[x][i]=f[ f[x][i-1] ][i-1];
 66            quan[x][i]=max( quan[x][i-1],quan[ f[x][i-1] ][i-1] );
 67      }
 68      for(int i=first[x];i;i=next[i]){
 69           if(height[to1[i]]==0)
 70           {
 71             f[ to1[i] ][0]=x;
 72             quan[ to1[i] ][0]=ww[i];
 73             dfs(to1[i],deep+1);        
 74           }
 75      }      
 76 }
 77 
 78 int lca(int x,int y){
 79        if(height[x]<height[y]) { int t=x;x=y;y=t; }
 80        int t=0;
 81        while((1<<t) <=height[x]) t++;
 82        t--;
 83        int ans1=-0x7ffffff,ans2=-0x7ffffff;
 84        for(int i=t;i>=0;i--){
 85           if(height[x]-(1<<i)>=height[y]) {
 86               ans1=max(ans1,quan[x][i]);
 87               x=f[x][i];        
 88           }
 89        }  
 90        if(x==y) return ans1;
 91        for(int i=t;i>=0;i--){
 92           if(f[x][i]!=f[y][i]){
 93              ans1=max(ans1,quan[x][i]); ans2=max(ans2,quan[y][i]);
 94              x=f[x][i];y=f[y][i];                     
 95           }        
 96        }
 97        int zong1,zong2;
 98        zong1=max(ans1,quan[x][0]);
 99        zong2=max(ans2,quan[y][0]);
100        return max(zong1,zong2);
101 }
102 
103 inline void work(){
104     qsort(1,m);
105     for(int i=1;i<=n;i++)    father[i]=i; 
106     int i=1,j=0;
107     int yigong=0;
108     while(i<=m){
109        int r1=find(u[i]);int r2=find(to[i]);
110        hebing(r1,r2);
111        yigong++;            
112        j++; next[j]=first[u[i]]; first[u[i]]=j;ww[j]=w[i]; to1[j]=to[i]; u1[j]=u[i];
113        j++; next[j]=first[to[i]]; first[to[i]]=j;ww[j]=w[i]; to1[j]=u[i]; u1[j]=to[i];
114        i++;
115        while(find(u[i])==find(to[i]) && i<=m) 
116            i++;
117     }
118     for(int i=1;i<=n;i++)
119      if(father[i]==i)
120      {
121         dfs(i,1);
122      }
123 }
124 
125 int main()
126 {
127     n=getint();m=getint();int q=getint();
128     int ljh,jump,jumpjump;
129     for(int i=1;i<=m;i++){
130           ljh=getint();jump=getint();jumpjump=getint();
131           u[i]=ljh;to[i]=jump;w[i]=jumpjump;  
132     } 
133     
134     work();
135     for(int i=1;i<=q;i++){
136         ljh=getint();jump=getint();
137         int ans=lca(ljh,jump);
138         printf("%d\n",ans);        
139     }
140     return 0;
141 }

 

BZOJ3732 Network

标签:

原文地址:http://www.cnblogs.com/ljh2000-jump/p/5468335.html

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