bzoj 2654 tree - 二分法 - 最小生成树
Input
Output
Sample Input
2 2 1
0 1 1 1
0 1 2 0
Sample Output
2
Hint
原数据出错,现已更新 by liutian,但未重测---2016.6.24
显然是MST,但是在Kruskal的过程中我们无法控制白边的数量。如果考虑修改边值,可以发现如果给白边的边权都加上一个delta,那么白边的数量随着delta的增大而减小。所以可以二分它去控制白边的数量。
Code
/**
* bzoj
* Problem#2654
* Accepted
* Time:1892ms
* Memory:3052k
*/
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<vector>
#include<stack>
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std;
typedef bool boolean;
const signed int inf = (signed)((1u << ) - );
#define smin(a, b) a = min(a, b)
#define smax(a, b) a = max(a, b)
#define max3(a, b, c) max(a, max(b, c))
#define min3(a, b, c) min(a, min(b, c))
template<typename T>
inline boolean readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-' && x != -);
if(x == -) {
ungetc(x, stdin);
return false;
}
if(x == '-'){
x = getchar();
aFlag = -;
}
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
u *= aFlag;
return true;
} typedef class union_found{
public:
int *f;
union_found():f(NULL) {}
union_found(int points) {
f = new int[(const int)(points + )];
clear(points);
}
int find(int x) {
if(f[x] != x) return f[x] = find(f[x]);
return f[x];
}
void unit(int fa, int so) {
int ffa = find(fa);
int fso = find(so);
f[fso] = ffa;
}
boolean connected(int a, int b) {
return find(a) == find(b);
}
void clear(int points) {
for(int i = ; i <= points; i++)
f[i] = i;
}
}union_found; int delta = ; typedef class Edge {
public:
int from;
int end;
int val;
boolean col; inline int getVal() const {
if(col) return val + delta;
return val;
}
}Edge; boolean operator < (const Edge& a, const Edge& b) {
return a.getVal() < b.getVal();
} int n, m, lim;
union_found uf;
Edge* edge; inline void init() {
readInteger(n);
readInteger(m);
readInteger(lim);
uf = union_found(n);
edge = new Edge[(const int)(m + )];
for(int i = ; i < m; i++) {
readInteger(edge[i].from);
readInteger(edge[i].end);
readInteger(edge[i].val);
readInteger(edge[i].col);
edge[i].col ^= ;
}
} int res = ;
int kruskal(int mid) {
delta = mid;
res = ;
uf.clear(n);
sort(edge, edge + m);
int fw = , fin = ;
for(int i = ; i < m; i++) {
if(!uf.connected(edge[i].from, edge[i].end)) {
uf.unit(edge[i].from, edge[i].end);
fw += edge[i].col, fin ++, res += edge[i].val;
}
}
return fw;
} inline void solve() {
int l = -, r = , c;
while(l <= r) {
int mid = (l + r) >> ;
if((c = kruskal(mid)) < lim) r = mid - ;
else if(c > lim) l = mid + ;
else break;
}
printf("%d\n", res);
} int main() {
init();
solve();
return ;
}
bzoj 2654 tree - 二分法 - 最小生成树的更多相关文章
- BZOJ 2654: tree(二分 最小生成树)
Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 2901 Solved: 1196[Submit][Status][Discuss] Descript ...
- BZOJ 2654: tree( 二分 + MST )
我们给白色的边增加权值 , 则选到的白色边就会变多 , 因此可以二分一下. 不过这道题有点小坑... ------------------------------------------------- ...
- BZOJ 2654: tree Kruskal+二分答案
2654: tree Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1863 Solved: 736[Submit][Status][Discuss ...
- BZOJ 2654: tree
Description \(n\) 个点, \(m\) 条边,边有权值和黑/白色,求含有 \(need\) 个白边的生成树. Sol 二分+Kruskal. 将每条白边都加上一个权值,然后跑最小生成树 ...
- [BZOJ 2654]tree(陈立杰)
Description 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. Input 第一行V,E,need分别表示点数,边数和需要的白色 ...
- hdu 4253 Two Famous Companies BZOJ 2654 tree
[题意]:给出n个点,m条边,边分为两种,一种是A公司的,一种是B公司的.边上有权值,问用n-1条边把n个点连起来的最小费用是多少,其中A公司的边刚好有k条.题目保证有解. 思路:我们发现,如果我们给 ...
- bzoj 2654 tree 二分+kruskal
tree Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 2739 Solved: 1126[Submit][Status][Discuss] Des ...
- BZOJ 2654 tree(二分答案+并查集)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2654 [题目大意] 给你一个无向带权连通图,每条边是黑色或白色. 让你求一棵最小权的恰 ...
- bzoj 2212 Tree Rotations
bzoj 2212 Tree Rotations 考虑一个子树 \(x\) 的左右儿子分别为 \(ls,rs\) .那么子树 \(x\) 内的逆序对数就是 \(ls\) 内的逆序对数,\(rs\) 内 ...
随机推荐
- 没有动态库链接:可执行的文件大小一个就有几百兆 Dynamic-Link Libraries
dynamic link library Dynamic-Link Libraries (Windows) https://msdn.microsoft.com/en-us/library/windo ...
- 一键安装openstack juno 之controller node.
原文名称: OpenStack Juno Scripted Installation on CentOS 7 Step I: 本机信息配置 CONTROLLER_IP=192.168.173.133 ...
- GA安装
- mybatis联接查询例子
where判断如果放在最外层就是对连接查询后的结果经行筛选. SELECT * from ( and lw_area.area_id like '35%' ) la LEFT JOIN ( selec ...
- gitlab启用https的配置
vim /etc/gitlab/gitlab.rb external_url 'https://101.101.101.63' #启用https,默认是http (改端口:external_ur ...
- CentOS工作内容(一)CentOS6.4的安装 hwclock和date
CentOS工作内容(一)CentOS6.4的安装 hwclock和date 光碟安装 分配20G磁盘空间 插入光碟 选择第一项安装 如果要急救的话请选择第三项 启动安装进程 跳过光碟检测 选择nex ...
- 【剑指offer】替换空格
一.题目: 请实现一个函数,将一个字符串中的空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. 二.思路: Python代码,先 ...
- PHP开发接口使用RSA进行加密解密方法
网络安全问题很重要,尤其是保证数据安全,遇到很多在写接口的程序员直接都是明文数据传输,在我看来这是很不专业的.本人提倡经过接口的数据都要进行加密解密之后进行使用. 这篇文章主要介绍使用PHP开发接口, ...
- POJ1258:Agri-Net(最小生成树模板题)
http://poj.org/problem?id=1258 Description Farmer John has been elected mayor of his town! One of hi ...
- openstack 部署笔记--基本环境准备
基础信息 配置:centos7.3 8G内存 4核处理器 单网卡 控制节点IP:192.168.15.243 计算节点IP:192.168.15.238 openstack 版本:ocata 配置信 ...