tree

时间限制: 3 Sec  内存限制: 512 MB

题目描述

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

输入

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

输出

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

样例输入

2 2 1
0 1 1 1
0 1 2 0

样例输出

2
  这道题正解是二分+最小生成树。本题最烦人的就是限制白边的数量因此我们需要一个东西使白边被优先或滞后考虑。由于克鲁斯卡尔是按照边权排序,我们可以给白边附上一个假边权,这样就可以使白边被优先或滞后考虑了。
  由于我们还需要保证改变后所有白边的相对大小不变,因此我们不能直接对白边附上某个值而是统一加上或减去某一个值,这样就可以保证相对大小不变了。至于这个值到底应当是多少,我们完全可以二分去查找,毕竟它是满足单调的。
  这时一种比较坑爹的情况就会出现了,如果这个图当所有白边边权加x后在最小生成树中的数目比need大,加x+1后数量又比need小,我们该如何处理呢?我们可以想一下,是什么样的黑边被替换了呢?就是白边新增的边的边权-附加的权值,因此如果现在算进最小生成树中的白边数大于need,其实它也是可以被算进结果的。
  
 #include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<string>
#include<cmath>
using namespace std;
int n,m,ne;
struct ro{
int from,to;
int l,col,rl;
}road[];
void build(int x,int y,int bh,int z,int zx){
road[bh].from=x;
road[bh].to=y;
road[bh].rl=road[bh].l=z;
road[bh].col=zx;
}
bool pd=;
int px(ro a,ro b){
if(a.l==b.l)
return a.col<b.col;
return a.l<b.l;
}
int fa[];
map<int,bool> fw2[][];
map<int,int> fw[][];
void init(int x){
for(int i=;i<=n;i++)
fa[i]=i;
for(int i=;i<=m;i++)
{
if(!road[i].col)
{
road[i].l=road[i].rl+x;
}
}
sort(road+,road+m+,px);
}
int find(int x){
if(fa[x]==x)
return x;
else
return fa[x]=find(fa[x]);
}
void hb(int x,int y){
int a=find(x);
int b=find(y);
if(a>b) fa[a]=b;
else fa[b]=a;
}
int sum=0x7fffffff;
bool check(int x){
int js=,ans=,js2=,js3=; for(int i=;i<=m;i++)
{
if(js==n-)break;
if(find(road[i].from)!=find(road[i].to))
{
js++;
if(road[i].col==)
{
js2++;
}
ans+=road[i].l;
hb(road[i].from,road[i].to);
}
}
if(js2>=ne)
{
sum=ans-ne*x;
return ;
}
pd=;
return ;
}
int main(){
scanf("%d%d%d",&n,&m,&ne);
for(int i=;i<=m;i++)
{
int x,y,z,zx;
scanf("%d%d%d%d",&x,&y,&z,&zx);
build(x,y,i,z,zx);
}
int li=-,ri=;
while(li<=ri)
{
int mid=(li+ri)/;
init(mid);
if(check(mid))
{
li=mid+;
}
else
ri=mid-;
}
printf("%d\n",sum);
//while(1);
return ;
}
 

[国家集训队2012]tree(陈立杰) 题解(二分+最小生成树)的更多相关文章

  1. [国家集训队2012]tree(陈立杰)

    [国家集训队2012]tree(陈立杰) 题目 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树.题目保证有解. INPUT 第一行V,E,need分别表示 ...

  2. [国家集训队2012]middle(陈立杰)

    我是萌萌的传送门 我是另一个萌萌的传送门 脑残错误毁一下午…… 其实题解早就烂大街了,然而很久之前我只知道是二分答案+主席树却想不出来这俩玩意儿怎么一块儿用的……今天又翻了几篇题解才恍然大悟,是把权值 ...

  3. [COGS 1799][国家集训队2012]tree(伍一鸣)

    Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2 ...

  4. 洛谷.2619.[国家集训队2]Tree I(带权二分 Kruskal)

    题目链接 \(Description\) 给定一个无向带权连通图,每条边是黑色或白色.求一棵最小权的恰好有K条白边的生成树. \(Solution\) Kruskal是选取最小的n-1条边.而白边数有 ...

  5. 数据结构(动态树):[国家集训队2012]tree(伍一鸣)

    [问题描述] 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原 ...

  6. cogs1799 [国家集训队2012]tree(伍一鸣)

    LCT裸题 注意打标记之间的影响就是了 这个膜数不会爆unsigned int #include<cstdio> #include<cstdlib> #include<a ...

  7. P2619 [国家集训队2]Tree I(最小生成树+二分)

    P2619 [国家集训队2]Tree I 每次二分一个$x$,每条白边加上$x$,跑最小生成树 统计一下满足条件的最小值就好了. to me:注意二分不要写挂 #include<iostream ...

  8. Luogu P2619 [国家集训队2]Tree I(WQS二分+最小生成树)

    P2619 [国家集训队2]Tree I 题意 题目描述 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有\(need\)条白色边的生成树. 题目保证有解. 输入输出格式 输入格式 ...

  9. [国家集训队2012]middle

    http://cogs.pro:8080/cogs/problem/problem.php?pid=1763 二分答案x 把区间内>=x的数设为1,<x的数设为-1 左端点在[a,b]之间 ...

随机推荐

  1. 【Git】打标签

    打标签 同大多数 VCS 一样,Git 也可以对某一时间点上的版本打上标签.人们在发布某个软件版本(比如 v1.0 等等)的时候,经常这么做.本节我们一起来学习如何列出所有可用的标签,如何新建标签,以 ...

  2. 什么是YAML?

    YAML是"YAML不是一种标记语言"的外语缩写 [1] (见前方参考资料原文内容):但为了强调这种语言以数据做为中心,而不是以置标语言为重点,而用返璞词重新命名.它是一种直观的能 ...

  3. C# WebRequest POST上传数据

    WebRequest request = WebRequest.Create("http://www.cnsos.net"); // Set the Method property ...

  4. Android多线程(一)

    在Android应用的开发过程中,我们不可避免的要使用多线程,获取服务器数据.下载网络数据.遍历文件目录查找特定文件等等耗时的工作都离不开线程的知识.Android继承了Java的多线程体系,同时又实 ...

  5. Qt DLL总结【三】-VS2008+Qt 使用QPluginLoader访问DLL

    目录 Qt DLL总结[一]-链接库预备知识 Qt DLL总结[二]-创建及调用QT的 DLL Qt DLL总结[三]-VS2008+Qt 使用QPluginLoader访问DLL 开发环境:VS20 ...

  6. Excel求值表达式——太好用了

    这个需要通过宏表函数EVALUATE来实现,首先需要自定义名称.如果数据在A列,那么在B列自定义名称,按Ctrl+F3键,在“定义名称框”中选择“新建”,然后输入名称为“结果”,数据来源输入=EVAL ...

  7. 当一个控件属性不存在的时候,IDE会出错在这里(说明是TWinControl.ReadState在读属性,并执行相关动作)

    procedure TWinControl.ReadState(Reader: TReader); begin DisableAlign; try inherited ReadState(Reader ...

  8. CMake编译如何解决[-Werror,-Wformat-security] 问题

    在用Android Studio进行Android开发时,常常采用 java代码调用C++代码,即JNI调用native的开发模式. 在上层build.gradle编译脚本里面可以指定C++代码的编译 ...

  9. java多线程之多生产者-多消费者

    多生产者和多消费者是线程通信的经典案例,但是和生产者-消费者相比更为复杂,而且可能会产生程序假死. public class Product { private MyStack myStack; pu ...

  10. Spring与IoC

    控制反转(IOC,Inversion of Control),是一个概念,是一种思想. 指将传统上由程序代码直接操控的对象调用权交给容器,通过容器来实现对象的装配和管理.控制反转就是对对象控制权的转移 ...