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\) 内 ...
随机推荐
- [python-opencv]图像二值化【图像阈值】
图像二值化[图像阈值]简介: 如果灰度图像的像素值大于阈值,则为其分配一个值(可以是白色255),否则为其分配另一个值(可以是黑色0) 图像二值化就是将灰度图像上的像素值设置为0或255,也就是将整个 ...
- IE强制标准模式---标准模式与兼容模式设置
<meta http-equiv="X-UA-Compatible" content="edge" /> 这个是最有效的方法. 文档模式(docum ...
- SpringBoot @Transactional声明事务无效问题
查看系统支持的存储引擎:show engines; 查看表使用的引擎:show table status from db_name where name='table_name'; 修改表引擎方法: ...
- 一次性从git远程仓库中克隆到本地。
自动化工具 一次性从git远程仓库中克隆到本地. import os # git操作 将远程repo克隆到本地 def git_clone_cd_pull(url): # 获取仓库名称 如fullsp ...
- hdu1671Phone List(字典树)
#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h&g ...
- hover()与toggle()
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- python ddt 实现数据驱动一
ddt 是第三方模块,需安装, pip install ddt DDT包含类的装饰器ddt和两个方法装饰器data(直接输入测试数据) 通常情况下,data中的数据按照一个参数传递给测试用例,如果da ...
- !!【通达信】求教:如何对A股的所有股票按照某个选股指标的某个参数排序? - 理想论坛 中国人气最旺的股票论坛
http://www.55188.com/thread-7152852-1-1.html .401进入指标排序,然后占右键把指标更改为MACD即可.(注意401前投资面有一个点!)
- SQL Server查询中特殊字符的处理方法
SQL Server查询中,经常会遇到一些特殊字符,比如单引号“'”等,这些字符的处理方法,是SQL Server用户都应该需要知道的. 我们都知道SQL Server查询过程中,单引号“'”是特殊字 ...
- windows配置承载网络的一个批处理程序
@rem 这是windows中创建承载网络的相关命令title wifi热点@echo off set ssid=abcdeset key=123456789 :beginclsecho ------ ...