【bzoj2654】【tree】【二分+最小生成树】
来源:互联网 发布:js对象参数 编辑:程序博客网 时间:2024/05/29 15:15
Description
给你一个无向带权连通图,每条边是黑色或白色。让你求一棵最小权的恰好有need条白色边的生成树。
题目保证有解。
Input
第一行V,E,need分别表示点数,边数和需要的白色边数。
接下来E行
每行s,t,c,col表示这边的端点(点从0开始标号),边权,颜色(0白色1黑色)。
Output
一行表示所求生成树的边权和。
Sample Input
2 2 1
0 1 1 1
0 1 2 0
0 1 1 1
0 1 2 0
Sample Output
2
HINT
数据规模和约定
0:V<=10
1,2,3:V<=15
0,..,19:V<=50000,E<=100000
所有数据边权为[1,100]中的正整数。
题解:显然可以发现随着白边权值的增大。最小生成树中白边的个数不增。
然后根据这个性质我们就可以二分一个值,然后每次给白边加上这个值。看一下最小生成树中白边的个数。
最后答案再把它减去。
看起来思路非常简单,但是有一个很重要的细节。
如果在你的二分过程中如果给白边加上mid,你得到的白边数比need大。
给白边加上mid+1,你得到的白边比need小。
这种情况看似没法处理。
但是考虑一下克鲁斯卡尔的加边顺序。
可以发现如果出现这种情况,一定是有很多相等的白边和黑边。因为数据保证合法。
所以我们可以把一些白边替换成黑边。
所以我们要在白边数>=need的时候跟新答案。
具体用ans=ans-mid*need;即可。
代码:
#include<cstdio>#include<algorithm>#include<iostream>using namespace std;int fa[1000001],n,m,need,l(-105),r(105),mid,temp,ans,r1,r2,cnt,ans2;struct use{int st,en,c,v;}e[100010];int find(int x){if (x!=fa[x]) fa[x]=find(fa[x]);return fa[x];}bool cmp(use a,use b){if (a.v==b.v) return a.c<b.c;else return a.v<b.v;}void solve(){ sort(e+1,e+m+1,cmp); for (int i=1;cnt!=n-1;i++){ r1=find(e[i].st);r2=find(e[i].en); if (r1!=r2){fa[r1]=r2;cnt++;if (e[i].c==0) temp++;ans+=e[i].v;} }}int main(){ scanf("%d%d%d",&n,&m,&need); for (int i=1;i<=m;i++){ scanf("%d%d%d%d",&e[i].st,&e[i].en,&e[i].v,&e[i].c); e[i].st++;e[i].en++; } while (l<=r){ mid=(l+r)>>1; for (int i=1;i<=m;i++) {if (e[i].c==0) e[i].v+=mid;} for (int i=1;i<=n+1;i++) fa[i]=i;ans=0;temp=0;cnt=0; solve(); if (temp>=need) {l=mid+1;ans2=ans-need*mid;}else r=mid-1; for (int i=1;i<=m;i++) if (e[i].c==0) e[i].v-=mid; } printf("%d\n",ans2);}
0 0
- 【bzoj2654】【tree】【二分+最小生成树】
- 【二分+最小生成树】bzoj2654 tree
- bzoj2654 Tree 二分答案+最小生成树
- 【BZOJ2654】tree【二分】【最小生成树】
- bzoj2654 tree 最小生成树+二分验证
- [bzoj2654]tree 二分+最小生成树
- 【bzoj2654】【二分+最小生成树】tree
- [bzoj2654]tree(二分+最小生成树)
- 【二分+最小生成树】BZOJ2654[tree]题解
- 【二分+最小生成树】BZOJ2654 tree
- [bzoj2654][最小生成树][二分]tree
- bzoj2654: tree(二分+最小生成树)
- bzoj2654 二分+最小生成树
- bzoj2654 二分答案+最小生成树
- bzoj2654 tree(二分+kruskal)
- [WQS二分] BZOJ2654:tree
- bzoj2654 tree(kruskal+二分)
- BZOJ 2654 tree 二分+最小生成树
- 【html】The RadioButton control
- Handler
- FSWD_3_JavaScriptAdvance
- 单元测试、集成测试、系统测试和验收测试
- 三角形测试
- 【bzoj2654】【tree】【二分+最小生成树】
- 循循渐进的GenericServlet
- Catch That Cow
- Combinator组合子———— 模拟递归(一)
- CMake 问题指南
- PopUpWindow与PopUpMenu
- spring mvc 配置web.xml servlet.xml文件配置以及出现异常的解决方案
- LeetCode 18_4Sum
- cmd删除文件