Time Limit: 30 Sec Memory Limit: 512 MB

Description

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

题目保证有解。

Input

第一行\(V\),\(E\),\(need\)分别表示点数,边数和需要的白色边数。

接下来E行,每行\(s\),\(t\),\(c\),\(col\)表示这边的端点(点从\(0\)开始标号),边权,颜色(\(0\)白色\(1\)黑色)。

Output

一行表示所求生成树的边权和。

\(V\leq50000\),\(E\leq100000\),所有数据边权为\([1,100]\)中的正整数。

Sample Input

2 2 1
0 1 1 1
0 1 2 0

Sample Output

2

HINT

原数据出错,现已更新 by liutian,但未重测---2016.6.24

Solution

比较神仙的做法,自己暂时还是不能想到的。路还长着,也还要多做点题目来提升提升自己的思维能力。这道题先Mark着。

我们发现,如果将白边的权一起增加或减少一个值,那么不会对选择的黑边有影响。至于证明嘛,自己意会一下就好了嘛,应该都没问题吧,就不要太严格地证了。

那么我们二分白边增减的值,然后对修改后的图做最小生成树。如果出现最小生成树里面的白边数量刚好就是\(need\)的话,那么这个树的形态就是题目要求的最小生成树了。

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
#define lowbit(x) ((x)&(-(x)))
#define REP(i,a,n) for(register int i=(a);i<=(n);++i)
#define PER(i,a,n) for(register int i=(a);i>=(n);--i)
#define FEC(i,x) for(register int i=head[x];i;i=g[i].ne)
#define dbg(...) fprintf(stderr,__VA_ARGS__)
namespace io{const int SIZE=(1<<21)+1;char ibuf[SIZE],*iS,*iT,obuf[SIZE],*oS=obuf,*oT=oS+SIZE-1,c,qu[55];int f,qr;#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),(iS==iT?EOF:*iS++)):*iS++)inline void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;}inline void putc(char x){*oS++=x;if(oS==oT)flush();}template<class I>inline void read(I &x){for(f=1,c=gc();c<'0'||c>'9';c=gc())if(c=='-')f=-1;for(x=0;c<='9'&&c>='0';c=gc())x=x*10+(c&15);x*=f;}template<class I>inline void write(I x){if(!x)putc('0');if(x<0)putc('-'),x=-x;while(x)qu[++qr]=x%10+'0',x/=10;while(qr)putc(qu[qr--]);}struct Flusher_{~Flusher_(){flush();}}io_flusher_;
}//orz laofudasuan
using io::read;using io::putc;using io::write;
typedef long long ll;typedef unsigned long long ull;
template<typename A,typename B>inline bool SMAX(A&x,const B&y){return y>x?x=y,1:0;}
template<typename A,typename B>inline bool SMIN(A&x,const B&y){return y<x?x=y,1:0;}const int N=50000+7,M=100000+7;
int n,m,nd,x,y,z,opt,cnt1,cnt2,ans;
struct Graph{int x,y,z;bool operator<(const Graph&a)const{return z<a.z;}}bl[M],wh[M];//错误笔记:一定要记得打上const int fa[N];
inline int Find(int x){return fa[x]==x?x:fa[x]=Find(fa[x]);}
inline void Union(int x,int y){x=Find(x),y=Find(y);x!=y?fa[y]=x:0;}
inline bool Check(int k){for(register int i=1;i<=n;++i)fa[i]=i;int cnt=0,get=0;ans=0;for(register int i1=1,i2=1;i1<=cnt1||i2<=cnt2;){if(i1<=cnt1&&(i2>cnt2||bl[i1].z<wh[i2].z+k))x=Find(bl[i1].x),y=Find(bl[i1].y),z=bl[i1].z,++i1;else x=Find(wh[i2].x),y=Find(wh[i2].y),z=wh[i2].z+k,++i2,x!=y?++get:0;//错误笔记:注意判断里面是i2>cnt2不是cnt1 if(x==y)continue;++cnt;Union(x,y);ans+=z;if(cnt==n-1)break;}return get>=nd;
}
inline int Solve(){int l=-100,r=100;//错误笔记:这里的范围是-100..100,不是1..100。一开始以为只会出现直接选选的边多于need,实际上也有可能少于,都要考虑。 while(l<r){int mid=(l+r+1)>>1;if(Check(mid))l=mid;else r=mid-1;}Check(l);return ans-nd*l;
}int main(){
#ifndef ONLINE_JUDGEfreopen("BZOJ2654.in","r",stdin);freopen("BZOJ2654.out","w",stdout);
#endifread(n),read(m);read(nd);for(register int i=1;i<=m;++i){//错误笔记:m是边数,n是点数! read(x),read(y),read(z),read(opt);++x,++y;//错误笔记:点从0开始编号 if(opt)bl[++cnt1]=Graph{x,y,z};else   wh[++cnt2]=Graph{x,y,z};}sort(bl+1,bl+cnt1+1);sort(wh+1,wh+cnt2+1);write(Solve());putc('\n');
}

转载于:https://www.cnblogs.com/hankeke/p/9833784.html

BZOJ2654 Tree相关推荐

  1. WQS二分 学习笔记 + 例题([BZOJ2654]Tree、[联考2018]林克卡特树)

    目录 问题类型 WQS二分思路 形象地说 板题 题意 & 解法 CODE 省选题 题意 & 解法 CODE 问题类型 形如"恰好取 k 个--时的最优答案(并非具体方案)&q ...

  2. [BZOJ2654] tree

    2654: tree Time Limit: 30 Sec  Memory Limit: 512 MB Submit: 610  Solved: 225 [Submit][Status][Discus ...

  3. BZOJ2654: tree 二分答案+最小生成树

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

  4. BZOJ2654: tree(陈立杰)

    2654: tree(陈立杰) Time Limit: 30 Sec  Memory Limit: 512 MB Submit: 229  Solved: 91 [Submit][Status] De ...

  5. 洛谷2619/bzoj2654 Tree(凸优化+MST)

    bzoj的数据是真的水.. qwq 由于本人还有很多东西不是很理解 qwq 所以这里只写一个正确的做法. 首先,我们会发现,对于你选择白色边的数目,随着数目的上涨,斜率是单调升高的. 那么这时候我们就 ...

  6. BZOJ2654:tree(最小生成树,二分)

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

  7. [XSY]Tree Ext(矩阵树定理,拉格朗日插值,最小生成树,二分)

    Tree Ext 这道题相当于把3道题合了起来. 要求修复的边中恰好有 k 条白边: 五颜六色的幻想乡(附拉格朗日插值法求多项式系数 ) + bzoj2654 tree(WQS二分 新科技get) 是 ...

  8. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

  9. 「BZOJ2654」tree

    「BZOJ2654」tree 最小生成树+二分答案. 最开始并没有觉得可以二分答案,因为答案并不单调啊. 其实根据题意,白边的数目肯定大于need条,而最小生成树的白边数并不等于need(废话),可以 ...

最新文章

  1. 29个简单直观的移动设备网页设计
  2. 一位面试者提到直接调用vuex中mutations方法
  3. 苹果自动驾驶“排名垫底”,每1.1英里就发生一次脱离...
  4. 剑指 Offer 64. 求1+2+…+n(面试题中的短路与)
  5. shell整理(34)===date 命令的小脚本
  6. 如何进行影像建库及做ArcGIS Server Cache
  7. 为什么中国电气自动化工程师这么难招
  8. ansys命令流力磁耦合仿真
  9. 斐讯路由器宽带运营商服务器,斐讯(PHICOMM)路由器设置网址
  10. jenkins编译java项目时无法读取pom.xml文件
  11. python结构方程模型_SEM结构方程模型分析的数据需要至少多少样本量
  12. 2017年微商行业八大趋势
  13. reboot复位ipcam,为何不可靠?
  14. 全能修图工具:Pixelmator Pro for Mac
  15. linux安装无线网卡,ubuntu20.04.5安装无线网卡 WDN6200
  16. 如何快准狠地找到相关领域的经典文献?
  17. 安卓手机+python基于abd命令的自动打卡
  18. x265代码阅读:码率控制(一)
  19. 【SCNU课堂笔记】计划任务、进程管理、Linux启动流程(未完待续)
  20. css溢出文本省略号

热门文章

  1. 牛客网暑期ACM多校训练营(第五场)J-plan (模拟)
  2. 开发之没沟通误删客户数据库数据之找数据路
  3. SQL-Server使用点滴(二-系统表)
  4. sqlserver得到行号
  5. 盘点:移动服务 #AzureChat
  6. NET中对象的构建过程
  7. mysql 5.6.14源码安装_CentOS 6.4下编译安装MySQL 5.6.14详细步骤
  8. 工资10000元,应该交多少税?
  9. RFID 是什么意思
  10. 被单位开除,已经交了14年的养老保险,该怎么办?