zoukankan      html  css  js  c++  java
  • 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 ( '
    ' ) ;
    146         for ( int i = 1 ; i <= n ; ++i )printf ("%d : %d %d
    ", i , E_val[rank[ i ] ] , E_val[ i ]) ;
    147         putchar ( '
    ' ) ;
    148 }
    149 void DEBUG_ ( int m ) {
    150         putchar('
    ');
    151         for ( int i = 1 ; i <= m ; ++i ) printf ("%d %d %d
    " , 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
    " , Ans ) ;
    176                 }
    177         }
    178         return 0 ;
    179 }
    BZOJ 3727

    NOIP_RP++;

    2016-10-11 03:53:37

    (完)

     

  • 相关阅读:
    FTP命令行工具NCFTP
    XP 通过无线网卡 建立对等网
    Silverlight WCF 压缩
    EntityFramework Linq查询
    UCS2编码转换C#
    C#7Z压缩
    c#公钥加密私钥解密和验证
    SVN global ignore pattern for c#
    典型的DIV CSS三行二列居中高度自适应布局
    VC#窗体的大小设置
  • 原文地址:https://www.cnblogs.com/shadowland/p/5947855.html
Copyright © 2011-2022 走看看