BZOJ 2654 tree - 二分+最小生成树
2017-10-21 11:42
429 查看
先给出一种方案:
首先二分一个权值mid,然后给白边每一个边加上mid,求一个最小生成树,观察白边使用的个数,二分到白边等于need,ans=val-mid*need。
下面给出证明:
白边数是一定的,二分权值,mid大,显然选的白边数会减少,具有可二分性。
在研究ans的单调性:假设现在有两种情况,白边数均为need,且mid1<mid2现在假设给情况1的白色边权值都加上Δmid,而选出的边不变,那么必然不会更优
(二者的树形可能都会不一样,树形改变则一定不会比原来更差),于是ans1<=(val加Δmid后−mid+Δmid)=ans2
(胡证的啊我也不知道怎么证,好捉急啊。。。)
首先二分一个权值mid,然后给白边每一个边加上mid,求一个最小生成树,观察白边使用的个数,二分到白边等于need,ans=val-mid*need。
下面给出证明:
白边数是一定的,二分权值,mid大,显然选的白边数会减少,具有可二分性。
在研究ans的单调性:假设现在有两种情况,白边数均为need,且mid1<mid2现在假设给情况1的白色边权值都加上Δmid,而选出的边不变,那么必然不会更优
(二者的树形可能都会不一样,树形改变则一定不会比原来更差),于是ans1<=(val加Δmid后−mid+Δmid)=ans2
(胡证的啊我也不知道怎么证,好捉急啊。。。)
#include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=50005; struct edge { int x,y,d,val; bool operator < (const edge &x)const { return val<x.val||(val==x.val&&d<x.d); } }e[maxn<<1]; int n,m,need,sum; int fa[maxn]; inline int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); } bool judge(int mid) { int num=0; sum=0; for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=m;i++)if(!e[i].d) e[i].val+=mid; sort(e+1,e+m+1); for(int i=1;i<=m;i++) { int x=find(e[i].x); int y=find(e[i].y); if(x==y)continue; fa[x]=y; if(!e[i].d)num++; sum+=e[i].val; } for(int i=1;i<=m;i++)if(!e[i].d) e[i].val-=mid; return num>=need; } int main() { scanf("%d%d%d",&n,&m,&need); for(int i=1;i<=m;i++) { scanf("%d%d%d%d",&e[i].x,&e[i].y,&e[i].val,&e[i].d); e[i].x++;e[i].y++; } int l=-105,r=105,ans; while(l<r) { int mid=l+r>>1; if(judge(mid)) ans=sum-mid*need,l=mid+1; else r=mid; } printf("%d",ans); return 0; }
相关文章推荐
- bzoj2654: tree(二分+最小生成树)
- BZOJ 2654 tree(二分答案+最小生成树)
- [bzoj2654][最小生成树][二分]tree
- 二分+最小生成树【bzoj2654】: tree
- 【bzoj2654】【二分+最小生成树】tree
- bzoj 2654 tree (二分 + 最小生成树)
- 【BZOJ2654】tree【二分】【最小生成树】
- BZOJ 2654 tree 二分+最小生成树
- [bzoj2654]tree(二分+最小生成树)
- [bzoj2654]tree 二分+最小生成树
- 【bzoj2654】【tree】【二分+最小生成树】
- [bzoj2654]tree(最小生成树+二分)
- bzoj 2654: tree 二分+最小生成树
- 【二分+最小生成树】BZOJ2654[tree]题解
- BZOJ 2654 tree 详解(最小生成树 kruskal 二分)
- bzoj 2654: tree (二分+最小生成树)
- BZOJ 2654: tree 最小生成树+二分
- 【二分+最小生成树】BZOJ2654 tree
- 【二分+最小生成树】bzoj2654 tree
- BZOJ2654 tree 【二分 + 最小生成树】