zoukankan      html  css  js  c++  java
  • BZOJ2654: tree 二分答案+最小生成树

    Description

    给你一个无向带权连通图,每条边是黑色或白色。让你求一棵最小权的恰好有need条白色边的生成树。
    题目保证有解。

    Input

    第一行V,E,need分别表示点数,边数和需要的白色边数。
    接下来E行,每行s,t,c,col表示这边的端点(点从0开始标号),边权,颜色(0白色1黑色)。

    Output

    一行表示所求生成树的边权和。
    V<=50000,E<=100000,所有数据边权为[1,100]中的正整数。

    Sample Input

    2 2 1
    0 1 1 1
    0 1 2 0

    Sample Output

    2

    Solution

    这做法反正我是想不到的...

    考虑怎么让拎出来的白色边减少

    我们可以给白色边加个权值

    然后又因为这个权值有单调性,所以二分来求最小

    二分之后拿最小生成树判定就好了

    #include <bits/stdc++.h>
    
    using namespace std ;
    
    #define N 100010
    #define inf 0x3f3f3f3f
    
    int n , m , sum = 0 , ans = 0 ;
    struct node {
        int u , v , w , col ;
    } e[ N ] ;
    int cnt , ned , t = 0 ;
    int f[ N ] ;
    
    bool cmp( node a , node b ) {
        return ( !a.col ? a.w + t : a.w ) < ( !b.col ? b.w + t : b.w ) ;
    }
    
    int find( int x ) {
        if( f[ x ] == x ) return x ;
        return f[ x ] = find( f[ x ] ) ;
    }
    
    bool check( int x ) {
        t = x ;
        for( int i = 1 ; i <= n ; i ++ ) f[ i ] = i ;
        sort( e + 1 , e + cnt + 1 , cmp ) ;
        int tot = 0 ; sum = 0 ;
        for( int i = 1 ; i <= cnt ; i ++ ) {
            int x = find( e[ i ].u ) , y = find( e[ i ].v ) ;
            if( x != y ) {
                f[ y ] = x ;
                sum += e[ i ].w ;
                if( !e[ i ].col ) tot ++ ;
            } 
        }
        return tot >= ned ;
    }
    
    int main() {
        scanf( "%d%d%d" , &n , &m , &ned ) ;
        for( int i = 1 , u , v , w , col ; i <= m ; i ++ ) {
            scanf( "%d%d%d%d" , &u , &v , &w , &col ) ;
            e[ ++ cnt ].u = ++u ; e[ cnt ].v = ++v ; e[ cnt ].w = w ;
            e[ cnt ].col = col ;
        }
        int l = -1e5 , r = 1e5 ;
        while( l <= r ) {
            int mid = ( l + r ) >> 1 ;
            if( check( mid ) ) l = mid + 1 , ans = sum ; 
            else r = mid - 1 ;
        }
        printf( "%d
    " , ans ) ;
        return 0 ;
    }
  • 相关阅读:
    Pentaho
    sympy 解四元一次方程
    install R language on ubuntu
    pyside
    浙江省医院网上挂号
    mtu值相关
    Python 中除法运算需要注意的几点
    idea
    kilim
    good blog
  • 原文地址:https://www.cnblogs.com/henry-1202/p/BZOJ2654.html
Copyright © 2011-2022 走看看