zoukankan      html  css  js  c++  java
  • P2619 [国家集训队2]Tree I(最小生成树+二分)

    P2619 [国家集训队2]Tree I

    每次二分一个$x$,每条白边加上$x$,跑最小生成树

    统计一下满足条件的最小值就好了。

    to me:注意二分不要写挂

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,m,T,fa[50005],ans,tt;
    struct edge{int f,t,v,c;}a[100005],b[100005];
    inline bool cmp(edge A,edge B){return (A.v==B.v)?A.c<B.c:A.v<B.v;}
    int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    int kruskal(){
        int re=0,k=n-1; tt=0;
        for(int i=1;i<=n;++i) fa[i]=i;
        sort(b+1,b+m+1,cmp);
        for(int i=1;k&&i<=m;++i){
            int r1=find(b[i].f),r2=find(b[i].t);
            if(r1!=r2) --k,re+=(b[i].c^1),tt+=b[i].v,fa[r1]=r2;
        }return re;
    }
    bool F(int x){
        for(int i=1;i<=m;++i) b[i]=a[i],b[i].v+=(b[i].c^1)*x;
        return kruskal()>=T;
    }
    int main(){
        scanf("%d%d%d",&n,&m,&T);
        for(int i=1;i<=m;++i)
            scanf("%d%d%d%d",&a[i].f,&a[i].t,&a[i].v,&a[i].c),++a[i].f,++a[i].t;
        int l=-100,r=100;
        while(l<=r){//注意边界是l<=r!
            int mid=(l+r)/2;
            if(F(mid)) ans=tt-T*mid,l=mid+1;
            else r=mid-1;
        }printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    sass学习笔记1
    javascript 数组的深度复制
    div+css定位position详解
    滚动加载图片(懒加载)实现原理
    移动端布局经验
    js 扁平化输出数组
    axiso基本使用及python接收处理
    JSP内置对象
    JSP基本语法
    tomcat环境搭建
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/10816571.html
Copyright © 2011-2022 走看看