# BZOJ 3732 题解

## Output

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

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

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
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编辑  收藏  举报