BZOJ P2654 tree 【最小生成树】【二分答案】

原创 2018年04月17日 18:17:06

题目索引:https://www.lydsy.com/JudgeOnline/problem.php?id=2654

2654: tree

Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 2768  Solved: 1136
[Submit][Status][Discuss]

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

HINT

原数据出错,现已更新 by liutian,但未重测---2016.6.24

Source


题目分析:

       求满足题意的最小生成树的权值->首先要满足要求->选出的最小生成树有need条白边->可是选出的最小生成树不一定有need条白边这么办->对于每一次Kruskal->我们可以得到当前最小生成树中白边的数量Cnt->如果Cnt>need->白边的数量比所需要的多了->白边的权值太小->使每一条白边都加去一个值->使得有可能下一次跑Kruskal统计出来的Cnt减少->如果出现Cnt<need->白边的数量比所需要的少了->白边的权值太大->使每一条白边都减去一个值->使得有可能下一次跑Kruskal统计出来的Cnt增多->我们该如何修改白边的权值->白边的权值修改多少->得解->二分答案+生成树。

代码如下:

        

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define DB double
#define SG string
#define LL long long
#define Fp(A,B,C,D) for(A=B;A<=C;A+=D)
#define Fm(A,B,C,D) for(A=B;A>=C;A-=D)
#define Clear(A) memset(A,0,sizeof(A))
using namespace std;
const LL Max=1e5+5;
const LL Mod=1e9+7;
const LL Inf=1e18;
struct Node{
    LL C,X,Y,V;
    void Get(LL A,LL B,LL P,LL Q){
        C=A;X=B;Y=P;V=Q;
    }
}G[Max<<1];
LL N,M,W,Ans,Cnt,Tot,Left=-105,Mid,Right=105,C[Max<<1],X[Max<<1],Y[Max<<1],V[Max<<1],F[Max<<1];
inline LL Read(){
    LL X=0;char CH=getchar();bool F=0;
    while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
    while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();}
    return F?-X:X;
}
inline void Write(LL X){
    if(X<0)X=-X,putchar('-');
    if(X>9)Write(X/10);
    putchar(X%10+48);
}
bool Cmp(Node A,Node B){
    return A.V==B.V?A.C<B.C:A.V<B.V;
}
LL Find(LL X){
    return F[X]==X?X:Find(F[X]);
}
void Kruskal(){
    LL I,J,K;Ans=Cnt=0;
    Fp(I,1,N,1){
        F[I]=I;
    }
    Fp(I,1,M,1){
        G[I].Get(C[I],X[I],Y[I],V[I]);
        if(!G[I].C){
            G[I].V-=Mid;
        }
    }sort(G+1,G+1+M,Cmp);
    Fp(I,1,M,1){
        LL P=Find(G[I].X);
        LL Q=Find(G[I].Y);
        if(P!=Q){
            F[P]=Q;
            Ans+=G[I].V;
            if(!G[I].C){
                Cnt++;
            }
        }
    }
}
int main(){
    LL I,J,K;
    N=Read(),M=Read(),W=Read();
    Fp(I,1,M,1){
        X[I]=Read()+1;
        Y[I]=Read()+1;
        V[I]=Read();
        C[I]=Read();
    }
    while(Left<=Right){
        Mid=Left+Right>>1;
        Kruskal();
        if(Cnt>=W){
            Right=Mid-1;
            Tot=Ans+W*Mid;
        } else {
            Left=Mid+1;
        }
    }Write(Tot);
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yanyidu/article/details/79978616

【bzoj2654】【tree】【二分+最小生成树】

Description   给你一个无向带权连通图,每条边是黑色或白色。让你求一棵最小权的恰好有need条白色边的生成树。   题目保证有解。 Input   第一行V,E,need分别表示点...
  • sunshinezff
  • sunshinezff
  • 2015-09-26 14:04:06
  • 2609

BZOJ 题目1016: [JSOI2008]最小生成树计数(Kruskal+Matrix_Tree)

1016: [JSOI2008]最小生成树计数
  • yu_ch_sh
  • yu_ch_sh
  • 2015-08-12 20:38:19
  • 628

bzoj2654 Tree 二分答案+最小生成树

今天讲课时的课件变成了至少k条,然后发现不会做 然后我问了他下正确性证明,然后他就委掉了. 不过正好是k条的方法很简单,显然我们需要控制白边的数量,那么我们控制权值就行 二分边权加上多少,然后最小生成...
  • BPM136
  • BPM136
  • 2016-03-31 22:30:50
  • 467

[XOR最小生成树 期望 DP] BZOJ 4770 图样

myh的题解 orzz 实现起来有点细节要处理 可能是我太弱?我就这么写了个记忆化搜索 结果极限数据要3.5s 然后我就活生生的被卡常了#include #include #include #in...
  • u014609452
  • u014609452
  • 2017-03-12 11:35:30
  • 830

BZOJ 3316 JC loves Mkk 二分答案+单调队列

题目大意:给定一个环,要求在这个环上截取长度为偶数且在[L,R]区间内的一段,要求平均值最大 看到环果断倍增 看到平均值最大果断二分答案 看到长度[L,R]果断单调队列 对数组维护一个前缀和,...
  • PoPoQQQ
  • PoPoQQQ
  • 2015-01-23 19:26:53
  • 1559

BZOJ 2654 tree(二分答案+最小生成树)

2654: tree Description 给你一个无向带权连通图,每条边是黑色或白色。让你求一棵最小权的恰好有need条白色边的生成树。 题目保证有解。 Input 第一行V,E,nee...
  • weixin_39549105
  • weixin_39549105
  • 2017-11-15 22:45:55
  • 39

BZOJ P2654 tree

神题啊 二分给白色边加上的权值,然后kruscal看看有没有正好need条边 有的话直接输出就可以了 然后证明的话不会,大概是你每条白边都加上一定的值是不会影响到最后的结果的 当然你也可以当做...
  • mdnd1234
  • mdnd1234
  • 2017-04-17 19:30:47
  • 124

BZOJ2258 文本校对 (Splay Hash 二分答案)

题目大意同bzoj1014,注意这里面的询问很鬼畜。要注意二分答案的上界的设定。题解题解见bzoj1014:读完题目我首先想到的是后缀数据结构,但是后缀数据结构并不支持修改操作。想了一会儿发现思路并不...
  • qq_33330876
  • qq_33330876
  • 2017-04-12 09:17:08
  • 346

bzoj2561 最小生成树 最小割

这道题目的做法有点神奇啊。。居然是用网络流。数据范围20w有点吓人啊。表示这种题目根本想不到是网络流,但告诉你是最小割还是恍然大悟的。        以最小生成树为例。把所有小于L的边取出来,显然这些...
  • lych_cys
  • lych_cys
  • 2015-12-01 21:05:56
  • 943

Bzoj1937:[Shoi2004]Mst 最小生成树:KM算法

题目链接:1937:[Shoi2004]Mst 最小生成树 首先由贪心思想可知,对于一条T上的边,我们要么不动,要么减少他的权值;对于一条不在T上的边,我们要么不动,要么增加他的权值 设di表示权...
  • qq_34025203
  • qq_34025203
  • 2016-03-25 11:04:45
  • 679
收藏助手
不良信息举报
您举报文章:BZOJ P2654 tree 【最小生成树】【二分答案】
举报原因:
原因补充:

(最多只允许输入30个字)