【bzoj2654]】tree
2016-07-23 19:39
253 查看
给白色边都加上一个值,二分这个值,使得选取的白边数量减少
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> using namespace std; typedef long long LL; #define N 100010 struct Node { int x,y,z,c; }e ,a ; int n,m,need; LL ans,cnt,tot; int l,r,mid; int f ; int cmp(Node a,Node b) { return a.z==b.z ? a.c<b.c : a.z<b.z; } int find(int x) { return f[x]!=x ? f[x]=find(f[x]) : f[x]; } void kruskal() { cnt=0,ans=0; int k=0; for (int i=1;i<=n;i++) f[i]=i; for (int i=1;k<n-1;i++) { int fa=find(e[i].x); int fb=find(e[i].y); if (fa!=fb) { f[fa]=fb; ans+=e[i].z; k++; if (!e[i].c) cnt++; } } } int main() { scanf("%d%d%d",&n,&m,&need); for (int i=1;i<=m;i++) scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].z,&a[i].c),a[i].x++,a[i].y++; l=-1010,r=1010; while (l<=r) { mid=(l+r)>>1; for (int i=1;i<=m;i++) e[i]=a[i]; for (int i=1;i<=m;i++) if (!e[i].c) e[i].z-=mid; sort(e+1,e+m+1,cmp); kruskal(); if (cnt<need) l=mid+1; else r=mid-1,tot=ans+need*mid; } printf("%lld\n",tot); return 0; }
相关文章推荐
- ACM暑期集训——专题一[最短路Dijkstra算法]
- [置顶] Token原理以及应用
- 逻辑运算符的短路特性
- 线段树
- 小结:c# setter属性注入
- HDU 2087 剪花布条 kmp
- HDU 2066 一个人的旅行
- 发送短信验证码计时
- CSS伪类和伪元素的本质区别
- android天气预报(二)
- MFC文档读取TXT文件中的数据并传输到对话框中
- javascript基础
- HDU5363:Key Set
- 如何解决兼容性问题
- 【技巧】简单理解快速幂(求模)
- 【codefors】贪心
- java-基础-集合hashset
- UnicodeDecodeError: 'ascii' codec can't decode byte 0xc1 in position 7: ordinal not in range(128)
- python核心编程学习笔记-2016-07-23-03-反单引号
- Visual Studio Code + live-server编辑和浏览HTML网页