「一本通 3.1 练习 4」Tree 题解
题目描述
原题来自: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 题解的更多相关文章
- 「LOJ#10051」「一本通 2.3 例 3」Nikitosh 和异或(Trie
题目描述 原题来自:CODECHEF September Challenge 2015 REBXOR 1≤r1<l2≤r2≤N,x⨁yx\bigoplus yx⨁y 表示 ...
- LOJ#10117. 「一本通 4.1 练习 2」简单题
LOJ#10117. 「一本通 4.1 练习 2」简单题 题目描述 题目来源:$CQOI 2006$ 有一个$n$个元素的数组,每个元素初始均为$0$.有$m$条指令,要么让其中一段连续序列数字反转— ...
- LOJ#10064. 「一本通 3.1 例 1」黑暗城堡
LOJ#10064. 「一本通 3.1 例 1」黑暗城堡 题目描述 你知道黑暗城堡有$N$个房间,$M$条可以制造的双向通道,以及每条通道的长度. 城堡是树形的并且满足下面的条件: 设$D_i$为如果 ...
- 「LOJ#10056」「一本通 2.3 练习 5」The XOR-longest Path (Trie
#10056. 「一本通 2.3 练习 5」The XOR-longest Path 题目描述 原题来自:POJ 3764 给定一棵 nnn 个点的带权树,求树上最长的异或和路径. 输入格式 第一行一 ...
- 「LOJ#10042」「一本通 2.1 练习 8」收集雪花 (map
题目描述 不同的雪花往往有不同的形状.在北方的同学想将雪花收集起来,作为礼物送给在南方的同学们.一共有 n 个时刻,给出每个时刻下落雪花的形状,用不同的整数表示不同的形状.在收集的过程中,同学们不希望 ...
- 「LOJ#10043」「一本通 2.2 例 1」剪花布条 (KMP
题目描述 原题来自:HDU 2087 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? 输入格式 输入数据 ...
- 「LOJ#10015」「一本通 1.2 练习 2」扩散(并查集
题目描述 一个点每过一个单位时间就会向 444 个方向扩散一个距离,如图所示:两个点 a .b 连通,记作 e(a,b),当且仅当 a .b的扩散区域有公共部分.连通块的定义是块内的任意两个点 u.v ...
- LOJ #10131 「一本通 4.4 例 2」暗的连锁
LOJ #10131 「一本通 4.4 例 2」暗的连锁 给一棵 \(n\) 个点的树加上 \(m\) 条非树边 , 现在需要断开一条树边和一条非树边使得图不连通 , 求方案数 . $n \le 10 ...
- #10042. 「一本通 2.1 练习 8」收集雪花 || 离散化 || 双指针法 || C++ || LOJ
题目:#10042. 「一本通 2.1 练习 8」收集雪花 看到网上没有这道题的题解,所以写一下. 要标记数字是否存在,看到x<=1e9,所以考虑用离散化,然后开一个last数组,last[i] ...
随机推荐
- 磁盘IO过高时的处理办法 针对系统中磁盘IO负载过高的指导性操作
磁盘IO过高时的处理办法 针对系统中磁盘IO负载过高的指导性操作 主要命令:echo deadline > /sys/block/sda/queue/scheduler 注:以下的内容仅是提供参 ...
- 查看 swappiness 值
Swap的使用频率 发表于 2017-06-02 | 分类于 Linux | 评论数: 通过调整swappiness的值, 可以调整系统使用 swap 的频率 该值越小, 表示越大限度的使用物理 ...
- [转载]centos 7(1611)安装笔记
centos 7(1611)安装笔记 麻烦 前天我把双系统笔记本里的 deepin 的磁盘分区直接从 Windows 7 磁盘管理里格式化了,结果悲催了,开不了机了,显示: 我以为是 Window ...
- zabbix自带的模板监控mysql
科技小能手 2017-11-12 1208浏览量 简介: zabbix官方支持监控MySQL,但直接使用默认的模板是不可用的,还需要经过额外的设置才可以使用.如果只需要对mysql数据库做简单的监控, ...
- PECcpu2006中执行单个测试程序的方法
PECcpu2006中执行单个测试程序的方法 2010-12-30 11:44:00 maray 阅读数 10055更多 分类专栏: 科学理论 版权声明:本文为博主原创文章,遵循CC 4.0 BY ...
- CentOS7开放端口以及常用的使用命令记录整理
CentOS7与以前常用的CentOS6还是有一些不同之处的,比如在设置开放端口的时候稍许有些不同,常用的iptables命令已经被firewalld代替.这几天正好有在CentOS7系统中玩Seaf ...
- liveCD版: CD光盘映像,和liveDVD一样,唯一的区别就是该版本中包含的软件包会少一点,安装系统时使用 U 盘或者CD光盘进行安装。
https://man.linuxde.net/download/CentOS/ CentOS,英文全称"Community Enterprise Operating System" ...
- STM32 串口接收大量数据导致死机
http://blog.csdn.net/origin333/article/details/49992383 以下文章出自上面的链接.感谢原创作者的分享. 在一项目中,使用STM32作为主控,程序运 ...
- Oracle中Table函数简单应用实例
说明 表函数可接受查询语句或游标作为输入参数,并可输出多行数据. 该函数可以平行执行,并可持续输出数据流,被称作管道式输出. 应用表函数可将数据转换分阶段处理,并省去中间结果的存储和缓冲表. 优势 1 ...
- Jsoup_Select 选择器
Jsoup_Select 选择器 一,概述 可直接解析某个 URL 地址.HTML 文本内容.它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数 ...