zoukankan      html  css  js  c++  java
  • 【bzoj2654]】tree

    给白色边都加上一个值,二分这个值,使得选取的白边数量减少

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
     
    typedef long long LL;
     
    #define N 100010
     
    struct Node
    {
        int x,y,z,c;
    }e[N],a[N];
     
    int n,m,need;
     
    LL ans,cnt,tot;
     
    int l,r,mid;
     
    int f[N];
     
    int cmp(Node a,Node b)
    {
        return a.z==b.z ? a.c<b.c : a.z<b.z;
    }
     
    int find(int x)
    {
        return f[x]!=x ? f[x]=find(f[x]) : f[x];
    }
     
    void kruskal()
    {
        cnt=0,ans=0;
        int k=0;
        for (int i=1;i<=n;i++)
            f[i]=i;
        for (int i=1;k<n-1;i++)
        {
            int fa=find(e[i].x);
            int fb=find(e[i].y);
            if (fa!=fb)
            {
                f[fa]=fb;
                ans+=e[i].z;
                k++;
                if (!e[i].c)
                    cnt++;  
            }
        }
    }
     
    int main()
    {
        scanf("%d%d%d",&n,&m,&need);
        for (int i=1;i<=m;i++)
            scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].z,&a[i].c),a[i].x++,a[i].y++;
        l=-1010,r=1010;
        while (l<=r)
        {
            mid=(l+r)>>1;
            for (int i=1;i<=m;i++)
                e[i]=a[i];
            for (int i=1;i<=m;i++)
                if (!e[i].c)
                    e[i].z-=mid;
            sort(e+1,e+m+1,cmp);
            kruskal();
            if (cnt<need)
                l=mid+1;
            else
                r=mid-1,tot=ans+need*mid;
        }
        printf("%lld
    ",tot);
        return 0;
    }
    

      

  • 相关阅读:
    代码重构编译---make
    clickhouse日期函数
    连续登陆天数+最大登陆天数
    clickhouse基本使用
    数组
    CK优化
    Hive查询优化~布隆过滤器使用
    Presto常见问题优化
    Presto原理解析
    几种排序说明
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5699384.html
Copyright © 2011-2022 走看看