题目描述

原题来自:2012 年国家集训队互测

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

输入格式

第一行V,E,need 分别表示点数,边数和需要的白色边数。

接下来E行,每行s,t,c,col表示这边的端点(点从0开始标号),边权,颜色(0白色,1黑色)。

输出格式

一行表示所求生成树的边权和。

样例

样例输入

2 2 1
0 1 1 1
0 1 2 0

样例输出

2

题解:

这个题要求在选取特定数量的基础上,构造一棵最小生成树。我们想一下,因为最小生成树所选择的是当前排序后最小的边(采用克鲁斯卡尔算法),如果我们把白色的边增大,那么这棵最小生成树里面的白色边就会少一些(因为边越大,排序的次序就越靠后),反之亦然。那么我们跑一个二分,把所有白边减一个mid,如果在此时最小生成树的白边数量比题目要求大,就说明目前mid的值大了,将其减少,否则将其增大。当此时最小生成树的白边数量等于题目所给的need时,说明此时的最小生成树即使满足题目要求的最佳情况,且因为此时最小生成树的值是在所有白边都减了一个mid的基础之上,所以答案还需增加一个need*mid;
有一位大佬问了我一个问题:

个人认为你并没有说明可以一定可以取到一个值使得恰好为k个

那么下面附上我的回答(感谢这位大佬!!!)

因为mid的值是没有范围的,所以我们可以通过mid的大小让所有的白边比最小的黑边还小,或者让他们比最大的黑边还大,那么在确保黑边有n-1条后,我们可以让白边的数量通过mid确定范围为0~n-1,所以一定有一个值使得恰好为k个(只要黑边数量大于n-1)

代码

#include<bits/stdc++.h>
using namespace std; struct zz{
int u,v,w,col;
}a[100005]; int pre[50005];
int n,m,k; int Find(int x){
if(pre[x]!=x){
pre[x]=Find(pre[x]);
}
return pre[x];
} bool cmp(zz x,zz y){
if(x.w!=y.w)
return x.w<y.w;
return x.col<y.col; //如果两个值相同,白色放前面(或者说是优先考虑白色),如果不相同,那么根据克鲁斯卡尔,权值小的放前面;
} int CHEAK(int pd,int mid){ //克鲁斯卡尔,如果pd为一,那么说明 我们在统计最小生成树的权值和,如果等于0,那么说明我们在判断白边的个数;
for(int i=1;i<=m;i++){
if(a[i].col==0){
a[i].w-=mid; //全部减去mid;
}
}
for(int i=0;i<n;i++)
pre[i]=i;
sort(a+1,a+m+1,cmp);
int cnt=0,toto=0,sum=0;
for(int i=1;i<=m;i++){
int fx=Find(a[i].u),fy=Find(a[i].v);
if(fx==fy)
continue;
pre[fx]=fy;
sum+=a[i].w;
if(a[i].col==0)
cnt++; //如果是白边,则统计;
toto++;
if(toto==n-1) break;
}
for(int i=1;i<=m;i++){
if(a[i].col==0)
a[i].w+=mid; //减了之后别忘加回来!!!
}
if(pd==0)
return cnt;
return sum;
} int main(){
cin>>n>>m>>k;
for(int i=1;i<=m;i++){
scanf("%d%d%d%d",&a[i].u,&a[i].v,&a[i].w,&a[i].col);
}
int l=-105,r=105; //二分边界
int ans=105; //统计最后减去的mid;
while(l<=r){
int mid=(l+r)/2;
int pd=CHEAK(0,mid);
if(pd>=k)
r=mid-1,ans=mid;
else
l=mid+1;
}
cout<<CHEAK(1,ans)+k*ans; //答案记得加上减去的mid;
}

「一本通 3.1 练习 4」Tree 题解的更多相关文章

  1. 「LOJ#10051」「一本通 2.3 例 3」Nikitosh 和异或(Trie

    题目描述 原题来自:CODECHEF September Challenge 2015 REBXOR 1​​≤r​1​​<l​2​​≤r​2​​≤N,x⨁yx\bigoplus yx⨁y 表示 ...

  2. LOJ#10117. 「一本通 4.1 练习 2」简单题

    LOJ#10117. 「一本通 4.1 练习 2」简单题 题目描述 题目来源:$CQOI 2006$ 有一个$n$个元素的数组,每个元素初始均为$0$.有$m$条指令,要么让其中一段连续序列数字反转— ...

  3. LOJ#10064. 「一本通 3.1 例 1」黑暗城堡

    LOJ#10064. 「一本通 3.1 例 1」黑暗城堡 题目描述 你知道黑暗城堡有$N$个房间,$M$条可以制造的双向通道,以及每条通道的长度. 城堡是树形的并且满足下面的条件: 设$D_i$为如果 ...

  4. 「LOJ#10056」「一本通 2.3 练习 5」The XOR-longest Path (Trie

    #10056. 「一本通 2.3 练习 5」The XOR-longest Path 题目描述 原题来自:POJ 3764 给定一棵 nnn 个点的带权树,求树上最长的异或和路径. 输入格式 第一行一 ...

  5. 「LOJ#10042」「一本通 2.1 练习 8」收集雪花 (map

    题目描述 不同的雪花往往有不同的形状.在北方的同学想将雪花收集起来,作为礼物送给在南方的同学们.一共有 n 个时刻,给出每个时刻下落雪花的形状,用不同的整数表示不同的形状.在收集的过程中,同学们不希望 ...

  6. 「LOJ#10043」「一本通 2.2 例 1」剪花布条 (KMP

    题目描述 原题来自:HDU 2087 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? 输入格式 输入数据 ...

  7. 「LOJ#10015」「一本通 1.2 练习 2」扩散(并查集

    题目描述 一个点每过一个单位时间就会向 444 个方向扩散一个距离,如图所示:两个点 a .b 连通,记作 e(a,b),当且仅当 a .b的扩散区域有公共部分.连通块的定义是块内的任意两个点 u.v ...

  8. LOJ #10131 「一本通 4.4 例 2」暗的连锁

    LOJ #10131 「一本通 4.4 例 2」暗的连锁 给一棵 \(n\) 个点的树加上 \(m\) 条非树边 , 现在需要断开一条树边和一条非树边使得图不连通 , 求方案数 . $n \le 10 ...

  9. #10042. 「一本通 2.1 练习 8」收集雪花 || 离散化 || 双指针法 || C++ || LOJ

    题目:#10042. 「一本通 2.1 练习 8」收集雪花 看到网上没有这道题的题解,所以写一下. 要标记数字是否存在,看到x<=1e9,所以考虑用离散化,然后开一个last数组,last[i] ...

随机推荐

  1. 小米华为vivooppo手机记录隐私证据查询

    1.在拨号界面输入:*#*#4636#*#* 2.在输入代码之后 手机会自动跳转到下面这个页面 就可以查看她到底拿着手机在干嘛 2 输入下面代码可以检测小米手机的各种信息 *#*#64663#*#* 

  2. shell进阶之tree、pstree、lsof命令详解

    一.tree命令详解: 主要功能是创建文件列表,将所有文件以树的形式列出来 -a 显示所有文件和目录. -A 使用ASNI绘图字符显示树状图而非以ASCII字符组合. -C 在文件和目录清单加上色彩, ...

  3. python3 xlrd包的用法

    一.xlrd的安装 pip install xlrd 二.xlrd使用介绍 1.导入模块 import xlrd 2.打开Excel文件,实例化为readbook readbook = xlrd.op ...

  4. 使用Mybatis插件 PageHelper 模拟百度分页(Day_20)

    生活中,要学会沉淀生命,沉淀心情,沉淀自己 模拟百度分页最终实现效果如图: 本篇博客运行环境 JDK8 + IntelliJ IDEA 2018.3 + Tomcat 8.5.31 准备好了我们就开始 ...

  5. MYSQL数据库快速添加测试数据方法

    先添加两条数据,这里最好添加两条不一样的数据 INSERT INTO "表名"(**, **) VALUES (**,**),(**,**) 然后再次添加数据,这次把查询到的数据添 ...

  6. 在Visual Studio 中使用git——分支管理-上(八)

    在Visual Studio 中使用git--什么是Git(一) 在Visual Studio 中使用git--给Visual Studio安装 git插件(二) 在Visual Studio 中使用 ...

  7. 服务器ip迁移纪要

    21楼机房之前已配25网段静态ip,机架上14台服务器接22楼机房交换机,同样25网段. 实际有两种情况, a.25网段ip没有被他人占用,这种情况无需更改ip. b.该IP已被外部使用,ip冲突,无 ...

  8. Step By Step(Lua函数)

    Step By Step(Lua函数) 一.函数:    在Lua中函数的调用方式和C语言基本相同,如:print("Hello World")和a = add(x, y).唯一的 ...

  9. Python+Selenium学习笔记16 - unittest单元测试框架

    unittest单元测试框架包括 Test Case,  Test Suite, Test Runner, Test Fixture Test Cases 组成Test Suite, Test Run ...

  10. Tensor Core技术解析(上)

    Tensor Core技术解析(上) NVIDIA在SIGGRAPH 2018上正式发布了新一代GPU架构--Turing(图灵),黄仁勋称Turing架构是自2006年CUDA GPU发明以来最大的 ...