[国家集训队2012]tree(陈立杰)
[国家集训队2012]tree(陈立杰)
题目
给你一个无向带权连通图,每条边是黑色或白色。让你求一棵最小权的恰好有need条白色边的生成树。
题目保证有解。INPUT
第一行V,E,need分别表示点数,边数和需要的白色边数。
接下来E行
每行s,t,c,col表示这边的端点(点从0开始标号),边权,颜色(0白色1黑色)。OUTPUT
一行表示所求生成树的边权和。
SAMPLE
INPUT
2 2 1
0 1 1 1
0 1 2 0
OUTPUT
2
数据规模
0:V<=10
1,2,3:V<=15
0,..,19:V<=50000,E<=100000
所有数据边权为[1,100]中的正整数。
解题报告
国家集训队的题,果然是好题= =
首先,我们观察题面,显然与最小生成树有什么关系,但是,直接跑最小生成树显然也是不合理的,那么问题就在于,如何在跑最小生成树的同时,还能保证白边的个数?
正解是个很神奇的东西——二分
首先我们想怎么二分,我们注意到,边权的范围很小,是$[1,100]$,那么,我们是否可以通过控制白边的边权,达到在最小生成树中控制白边的数量呢?
显然可以。
我们以$Kruskal$算法为例,我们进行$Kruskal$时,是以每条边的边权为依据,进行从小到大排序,然后从小到大取出各个边,不断加入连通分量中,最后形成最小生成树。那么,当我们改变某一些边的权值时,我们按权值排序得出的边的序列也一定就会不一样,那么,我们就可以通过控制权值来控制加入生成树的白边数了。
具体做法:
在$[-100,100]$中二分得到$mid$,让所有白边的权值加上该$mid$值,跑$Kruskal$,直到得到最终结果
但是,只是这样就可以了吗?
显然不是。
我们考虑,假如我们点很少,只有$10+$个点,但是我们的边很多,达到了$100000$,而且权值范围还被限制在了$[1,100]$,那么显然,会有许多等价的黑边与白边,即使加上了某一个权值,也可能会有很多白边与很多黑边相等价,当我们按照权值排序的同时,我们把黑边与白边混在了一起,然后我们就开始了$Kruskal$,那样的话,我们本来可以得到刚好$need$条白边,我们却把一些与黑边等价的白边扔进了生成树中,这样的话,我们本来可以得到最优解,却认为它是不合法的。
这时我们就需要处理一下这些等价的边。
具体做法:
在二分后判断时,我们不单单判断此时白边的数目是否等于$need$,而是将一切白边数大于等于$need$的情况全部考虑上,然后,我们加上了(或者是减去,因为我们有负数)许多为了控制生成树的权值,所以我们需要减去(或加上)这些权值,我们并不能将所有白边修改的权值修改回去,而是将$need\times mid$权值处理掉,因为假如我们处理所有的白边,我们可能将那些等价于黑边的白边也处理掉了,也就是相当于处理了黑边,显然是不合法的,所以我们只处理$need$条,也就是真正被当成白边的白边数量
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
inline int read(){
int sum(),f();
char ch(getchar());
for(;ch<''||ch>'';ch=getchar())
if(ch=='-')
f=-;
for(;ch>=''&&ch<='';sum=sum*+(ch^),ch=getchar());
return sum*f;
}
struct edge{
int s,e,w,col,tmp;
friend bool operator<(const edge &a,const edge &b){
return a.tmp==b.tmp?a.col<b.col:a.tmp<b.tmp;
}
}a[];
int n,m,need;
int fa[];
inline int find(int x){
if(fa[x]==x)
return x;
fa[x]=find(fa[x]);
return fa[x];
}
int tp;
inline bool krus(){
tp=;
int tot(),whit();
sort(a+,a+m+);
for(int i=;i<=m;++i){
int s(a[i].s),e(a[i].e);
int fs(find(s)),fe(find(e));
if(fs!=fe){
fa[fe]=fs;
if(a[i].col==)
++whit;
++tot;
tp+=a[i].tmp;
if(tot==n-)
break;
}
}
return whit>=need;
}
inline int gg(){
freopen("nt2012_tree.in","r",stdin);
freopen("nt2012_tree.out","w",stdout);
n=read(),m=read(),need=read();
for(int i=;i<=m;++i)
a[i].s=read()+,a[i].e=read()+,a[i].w=read(),a[i].col=read();
int l(-),r(),ans;
while(l<=r){
int mid((l+r)>>);
for(int i=;i<=n;++i)
fa[i]=i;
for(int i=;i<=m;++i){
if(a[i].col==)
a[i].tmp=a[i].w+mid;
else
a[i].tmp=a[i].w;
}
if(krus())
l=mid+,ans=tp-need*mid;
else
r=mid-;
}
printf("%d",ans);
return ;
}
int K(gg());
int main(){;}
[国家集训队2012]tree(陈立杰)的更多相关文章
- [国家集训队2012]tree(陈立杰) 题解(二分+最小生成树)
tree 时间限制: 3 Sec 内存限制: 512 MB 题目描述 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. 输入 第一行V, ...
- [国家集训队2012]middle(陈立杰)
我是萌萌的传送门 我是另一个萌萌的传送门 脑残错误毁一下午…… 其实题解早就烂大街了,然而很久之前我只知道是二分答案+主席树却想不出来这俩玩意儿怎么一块儿用的……今天又翻了几篇题解才恍然大悟,是把权值 ...
- 数据结构(动态树):[国家集训队2012]tree(伍一鸣)
[问题描述] 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原 ...
- [COGS 1799][国家集训队2012]tree(伍一鸣)
Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2 ...
- cogs1799 [国家集训队2012]tree(伍一鸣)
LCT裸题 注意打标记之间的影响就是了 这个膜数不会爆unsigned int #include<cstdio> #include<cstdlib> #include<a ...
- [国家集训队2012]middle
http://cogs.pro:8080/cogs/problem/problem.php?pid=1763 二分答案x 把区间内>=x的数设为1,<x的数设为-1 左端点在[a,b]之间 ...
- luogu P2619 [国家集训队2]Tree I
题目链接 luogu P2619 [国家集训队2]Tree I 题解 普通思路就不说了二分增量,生成树check 说一下坑点 二分时,若黑白边权有相同,因为权值相同优先选白边,若在最有增量时出现黑白等 ...
- [国家集训队2012]JZPFAR
[国家集训队2012]JZPFAR 题目 平面上有n个点.现在有m次询问,每次给定一个点(px, py)和一个整数k,输出n个点中离(px, py)的距离第k大的点的标号.如果有两个(或多个)点距离( ...
- P2619 [国家集训队2]Tree I(最小生成树+二分)
P2619 [国家集训队2]Tree I 每次二分一个$x$,每条白边加上$x$,跑最小生成树 统计一下满足条件的最小值就好了. to me:注意二分不要写挂 #include<iostream ...
随机推荐
- JSP-Runoob:JSP 页面重定向
ylbtech-JSP-Runoob:JSP 页面重定向 1.返回顶部 1. JSP 页面重定向 当需要将文档移动到一个新的位置时,就需要使用JSP重定向了. 最简单的重定向方式就是使用respons ...
- PCB 挺有意思的基数排序----C#代码实现
今天在头条看一个很有意思的排序算法[基数排序],以前所学习的排序算法都是基于数值对比的方式排序的,而这个算法挺有意思的非常独特.但从网上看到的例子通常是对个位,十位处理,并转为对应的桶索引的方式实现, ...
- spring基础学习---简单配置文件
- roundabout旋转幻灯
jquery.roundabout.js文件/** * jQuery Roundabout - v2.4.2 * http://fredhq.com/projects/roundabout * * M ...
- 悼念512汶川大地震遇难同胞——老人是真饿了 hdu 2187
在此对 曾经 努力参加 救援的人 致以深深的敬意 . 这一道题 挺简单的 就是简单的 结构体+贪心 而已 不过 用英文 注释 是一个 很大的 进步 , 以后 要习惯 http://acm.hdu ...
- 【POJ3255/洛谷2865】[Usaco2006 Nov]路障Roadblocks(次短路)
题目: POJ3255 洛谷2865 分析: 这道题第一眼看上去有点懵-- 不过既然要求次短路,那估计跟最短路有点关系,所以就拿着优先队列优化的Dijkstra乱搞,搞着搞着就通了. 开两个数组:\( ...
- cocos2d-js 开发常见问题
1. 编译android版本可能出现的问题记录 如果编译的时候报错.出现/platforms/android-14/arch-arm/usr/lib/crtend_so.o: Unknown EABI ...
- Jquery音频播放插件下载地址(有Html、JS、CSS、音频)
有详细的html文件.全部JS代码文件.Css样式文件.测试音频资料 音频播放插件下载链接(百度云): http://pan.baidu.com/s/1pKC904F 提取码评论留邮箱发送,谢谢!
- Redux 基础概念
Redux is a predictable state container for JavaScript apps.,亦即 Redux 希望能提供一个可以预测的 state 管理容器,让开发者可以可 ...
- ionic2\ionic3 自定义弹窗
ionic2及ionic3没有了popup及 其templateUrl属性 那我们如何对弹窗里加入自定义元素 从而达到自定义弹窗样式 那么就可以通过写h5页面来实现 自定义弹窗效果: 写个H5的弹窗及 ...