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

Input

第一行V,E,need分别表示点数,边数和需要的白色边数。
接下来E行,每行s,t,c,col表示这边的端点(点从0开始标号),边权,颜色(0白色1黑色)。

Output

一行表示所求生成树的边权和。
V<=50000,E<=100000,所有数据边权为[1,100]中的正整数。

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 - 二分法 - 最小生成树的更多相关文章

  1. BZOJ 2654: tree(二分 最小生成树)

    Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 2901  Solved: 1196[Submit][Status][Discuss] Descript ...

  2. BZOJ 2654: tree( 二分 + MST )

    我们给白色的边增加权值 , 则选到的白色边就会变多 , 因此可以二分一下. 不过这道题有点小坑... ------------------------------------------------- ...

  3. BZOJ 2654: tree Kruskal+二分答案

    2654: tree Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1863  Solved: 736[Submit][Status][Discuss ...

  4. BZOJ 2654: tree

    Description \(n\) 个点, \(m\) 条边,边有权值和黑/白色,求含有 \(need\) 个白边的生成树. Sol 二分+Kruskal. 将每条白边都加上一个权值,然后跑最小生成树 ...

  5. [BZOJ 2654]tree(陈立杰)

    Description 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. Input 第一行V,E,need分别表示点数,边数和需要的白色 ...

  6. hdu 4253 Two Famous Companies BZOJ 2654 tree

    [题意]:给出n个点,m条边,边分为两种,一种是A公司的,一种是B公司的.边上有权值,问用n-1条边把n个点连起来的最小费用是多少,其中A公司的边刚好有k条.题目保证有解. 思路:我们发现,如果我们给 ...

  7. bzoj 2654 tree 二分+kruskal

    tree Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 2739  Solved: 1126[Submit][Status][Discuss] Des ...

  8. BZOJ 2654 tree(二分答案+并查集)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2654 [题目大意] 给你一个无向带权连通图,每条边是黑色或白色. 让你求一棵最小权的恰 ...

  9. bzoj 2212 Tree Rotations

    bzoj 2212 Tree Rotations 考虑一个子树 \(x\) 的左右儿子分别为 \(ls,rs\) .那么子树 \(x\) 内的逆序对数就是 \(ls\) 内的逆序对数,\(rs\) 内 ...

随机推荐

  1. The Unique MST POJ - 1679 最小生成树判重

    题意:求一个无向图的最小生成树,如果有多个最优解,输出"Not Unique!" 题解: 考虑kruskal碰到权值相同的边: 假设点3通过边(1,3)连入当前所维护的并查集s. ...

  2. stress test - volume test

    D:\wamp64\bin\mysql\mysql5.7.11\bin>mysqlslap --delimiter=";" --query=" INSERT I N ...

  3. kubernetes实战(十六):k8s高可用集群平滑升级 v1.11.x 到v1.12.x

    1.基本概念 升级之后所有的containers会重启,因为hash值会变. 不可跨版本升级. 2.升级Master节点 当前版本 [root@k8s-master01 ~]# kubeadm ver ...

  4. 【HTML5】HTML5的自学路线

    HTML5的开发市场已越来越火爆,他已经与我们的生活息息相关,它也成为了我们生活中的一部分,比如我们在网上购物,玩手游等等,都存在html5的影子,也正是因为html5的高度影响力,吸引了许多人开始关 ...

  5. 7 jmeter之参数化

    badboy里参数化(前面4 jmeter badboy脚本开发技术详解已讲过) jmeter里参数化-1 用户参数 1.打开badboy工具,点击红色按钮开始录制,在地址栏目中输入地址:www.so ...

  6. 深度学习之TensorFlow(一)——基本使用

    一.目前主流的深度学习框架Caffe, TensorFlow, MXNet, Torch, Theano比较 库名称 开发语言 速度 灵活性 文档 适合模型 平台 上手难易 Caffe c++/cud ...

  7. [py][mx]django城市-教学机构-教师模型设计

    分析下城市-教学机构-教师模型设计 CourseOrg 课程信息 Teacher 教师信息 CityDict 城市信息 代码 from datetime import datetime from dj ...

  8. [py][mx]django课程模型

    课程模型分析 分3个表 先设计课程表, 这是1 在设计lesson表,添加一个外键,course. 课程 1 course 章节 n lesson 视频 n video 资源 n coursereso ...

  9. PAT World Cup Betting[非常简单]

    1011 World Cup Betting (20)(20 分) With the 2010 FIFA World Cup running, football fans the world over ...

  10. [LeetCode] 285. Inorder Successor in BST_Medium tag: Inorder Traversal

    Given a binary search tree and a node in it, find the in-order successor of that node in the BST. No ...