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
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
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 }
NOIP_RP++;
2016-10-11 03:53:37
(完)