BZOJ 3732 题解

3732: Network

Description

给你N个点的无向图 (1 <= N <= 15,000),记为:1…N。 
图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: d_j ( 1 < = d_j < = 1,000,000,000).

现在有 K个询问 (1 < = K < = 15,000)。 
每个询问的格式是:A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?

Input

第一行: N, M, K。 
第2..M+1行: 三个正整数:X, Y, and D (1 <= X <=N; 1 <= Y <= N). 表示X与Y之间有一条长度为D的边。 
第M+2..M+K+1行: 每行两个整数A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?

Output

 对每个询问,输出最长的边最小值是多少。

Sample Input

6 6 8
1 2 5
2 3 4
3 4 3
1 4 8
2 5 7
4 6 2
1 2
1 3
1 4
2 3
2 4
5 1
6 2
6 1

Sample Output

5
5
5
4
4
7
4
5

HINT

 

1 <= N <= 15,000 

1 <= M <= 30,000 

1 <= d_j <= 1,000,000,000 

1 <= K <= 15,000 

—————————————分割线—————————————

为了保证最长边最小,即求图的最小瓶颈生成树,原图的最小瓶颈生成树就是最小生成树。

 

代码:

 

  1 /**************************************************************
  2     Problem: 3732
  3     User: shadowland
  4     Language: C++
  5     Result: Accepted
  6     Time:372 ms
  7     Memory:32768 kb
  8 ****************************************************************/
  9  
 10 /* 
 11     树链剖分
 12     author : SHHHS
 13     2016-10-02 09:04:15 
 14 */
 15 #include "bits/stdc++.h"
 16  
 17 using namespace std ;
 18  
 19 struct MST{int x , y , val ; } ;
 20 struct Edge{int to , next , val ; } ;
 21 struct SegTree{int l , r , mintr ; } ;
 22 const int INF = 2147483647 ;
 23 const int maxN = 300010 ;
 24 typedef long long QAQ ;
 25  
 26 MST MST_e[ maxN ] ;
 27 Edge e [ maxN ] ;
 28 SegTree tr[ maxN << 2 ] ;
 29 int head[maxN] , father[maxN], DFN[maxN], hv[maxN],rank[maxN], E_val[maxN], start[maxN], pre[maxN];
 30 bool vis[maxN] ;
 31  
 32 int cnt , dfs_num ;
 33 QAQ Ans = INF ;
 34  
 35 void Init ( int n ){for ( int i = 1 ; i <= n ; ++i )father[ i ] = i ; }
 36 int getfa ( int x ){if(father[x] == x)return x ; else return father[ x ] = getfa( father[ x ] ) ; }
 37 inline bool cmp ( MST x , MST y ){ return x.val < y.val ; }
 38 inline int gmin ( int x , int y ){ return x < y ? y : x ; }
 39 inline void Union_Set ( const int x , const int y ){ father[ x ] = y ; }
 40 inline void Push_up ( int i ){tr[ i ].mintr = gmin (tr[ i << 1 | 1 ].mintr, tr[ i << 1 ].mintr) ; }
 41 inline void gswap ( int &x , int &y ) {int temp = x ; x = y ; y = temp ; }
 42 bool Check ( const int x , const int y ) { return getfa( x ) == getfa( y ) ? true : false ; }
 43  
 44 void Build_Tree ( int x , int y , int i ) {
 45         tr[ i ].l = x ;
 46         tr[ i ].r = y ;
 47         if ( x == y ) tr[ i ].mintr = E_val[ rank[ x ] ] ;
 48         else {
 49                 int mid = ( tr[ i ].l + tr[ i ].r ) >> 1 ;
 50                 Build_Tree ( x , mid , i << 1 ) ;
 51                 Build_Tree ( mid + 1 , y , i << 1 | 1 ) ;
 52                 Push_up ( i ) ;
 53         }
 54 }
 55  
 56 inline void Add_Edge ( const int x , const int y , const int _val ) {
 57         e[ ++cnt ].to = y ;
 58         e[ cnt ].val = _val ;
 59         e[ cnt ].next = head[ x ] ;
 60         head[ x ] = cnt ;
 61 }
 62  
 63 void MST ( int N , int M ) {
 64         int cnt_ = 0 ;
 65         Init ( N ) ;
 66         sort ( MST_e + 1 , MST_e + M + 1 , cmp ) ;
 67         for ( int i = 1 ; i <= M ; ++i ) {
 68                 int px = getfa ( MST_e[i].x ) ;
 69                 int py = getfa ( MST_e[i].y ) ;
 70                 if ( px == py ) continue ;
 71                 else {
 72                         Union_Set ( px , py ) ;
 73                         Add_Edge ( MST_e[i].x , MST_e[i].y , MST_e[i].val ) ;
 74                         Add_Edge ( MST_e[i].y , MST_e[i].x , MST_e[i].val ) ;
 75                         ++cnt_ ;
 76                 }
 77                 if ( cnt_ == N - 1 ) break ;
 78         }
 79 }
 80  
 81 int Init_DFS ( const int x , const int fa ) {
 82         vis[ x ] = true ;
 83         int cnt_ = 1 , max_ = 0 ;
 84         for ( int i = head[ x ] ; i ; i = e[ i ].next ) {
 85                 int temp = e[ i ].to ; 
 86                 if ( temp == fa ) continue ;
 87                 int _ = Init_DFS ( temp , x ) ;
 88                 if ( _ > max_ ) {
 89                         max_ = _ ;
 90                         hv[ x ] = temp ;
 91                 }
 92                 cnt_ += _;
 93         }   
 94         return cnt_ ;
 95 }
 96  
 97 void DFS ( const int x , const int fa ) {
 98         vis [ x ] = false ;
 99         if ( !start[ x ] ) start[ x ] = start[ fa ] ;
100         DFN[ x ] = ++ dfs_num ;
101         rank[ dfs_num ] = x ;
102         if ( hv[ x ] ) DFS ( hv[ x ] , x ) ;
103         for ( int i = head[ x ] ; i ; i = e[ i ].next ) {
104                 if ( e[ i ].to == fa ) continue ;
105                 E_val[ e[ i ].to ] = e[ i ] .val ;
106                 if ( e[ i ].to != hv[ x ] && e[ i ].to != fa && vis[ e[ i ].to ] == true ) {
107                         int temp = e[ i ].to ;
108                         start[ temp ] = temp ;
109                         pre [ temp ] = x ;
110                         DFS ( temp , x ) ;
111                 }
112         }
113 }
114  
115 QAQ Query_Tree ( int q , int w , int i ) { 
116         if ( q <= tr[i].l && w >= tr[i].r ) return tr[i].mintr;
117         else {
118                 int mid = ( tr[ i ].l + tr[ i ].r ) >> 1 ;
119                 if ( q > mid ) return Query_Tree ( q , w , i << 1 | 1) ;
120                 else if ( w <= mid ) return Query_Tree ( q , w , i << 1 ) ;
121                 else return gmin ( Query_Tree ( q , w , i << 1 | 1 ) , Query_Tree ( q , w , i << 1 ) ) ;
122         }
123 }
124  
125 void Solve ( const int x , const int y ) {
126         int px = x , py = y ;
127         while ( start[ px ] != start[ py ] ) {
128                 if ( DFN[ start[ px ] ] > DFN[ start[ py ] ] ) {
129                         Ans = gmin ( Ans , Query_Tree ( DFN[start[ px ]] , DFN[px] , 1 ) ) ;
130                         px = pre[ start[ px ] ] ;
131                 }
132                 else {//py跳 
133                         Ans = gmin ( Ans , Query_Tree ( DFN[start[ py ]] , DFN[py] , 1 ) ) ;
134                         py = pre[ start[ py ] ] ;
135                 }
136         }
137  
138         if ( px == py ) return ;
139         int dfn_px = DFN[ px ] , dfn_py = DFN[ py ] ;
140         if ( dfn_px  > dfn_py ) gswap ( dfn_px , dfn_py ) ;
141         Ans = gmin ( Ans , Query_Tree ( dfn_px + 1, dfn_py , 1 ) );
142 }
143  
144 void DEBUG__ ( int n ){
145         putchar ( '\n' ) ;
146         for ( int i = 1 ; i <= n ; ++i )printf ("%d : %d %d\n", i , E_val[rank[ i ] ] , E_val[ i ]) ;
147         putchar ( '\n' ) ;
148 }
149 void DEBUG_ ( int m ) {
150         putchar('\n');
151         for ( int i = 1 ; i <= m ; ++i ) printf ("%d %d %d\n" , MST_e[ i ].x , MST_e[ i ].y , MST_e[ i ].val) ;
152 }
153 int main ( ) {
154         int N , M , Q , _x , _y ;
155         scanf ( "%d%d%d" , &N , &M , &Q ) ;
156         for ( int i = 1 ; i <= M ; ++i )
157                 scanf ( "%d%d%d" , &MST_e[ i ].x , &MST_e[ i ].y , &MST_e[ i ].val ) ;
158         MST ( N , M ) ;
159    
160         Init_DFS ( 1 , 1 ) ;
161         start[ 1 ] = 1 ;
162         E_val[ 1 ] = -INF ;
163          
164         //DEBUG_( M );
165         DFS ( 1 , 1 ) ;
166  
167         Build_Tree ( 1 , dfs_num , 1 ) ;
168  
169         //DEBUG__( dfs_num ) ;
170         while ( Q-- ){
171                 Ans = -INF ;
172                 scanf ( "%d%d" , &_x , &_y ) ;
173                 if ( Check ( _x , _y ) ) {
174                         Solve ( _x , _y ) ;
175                         printf ( "%lld\n" , Ans ) ;
176                 }
177         }
178         return 0 ;
179 }
BZOJ 3727

NOIP_RP++;

2016-10-11 03:53:37

(完)

 

 

posted @ 2016-10-11 03:54  SHHHS  阅读(246)  评论(1编辑  收藏  举报