• [bzoj2654]tree_二分_kruskal


    tree bzoj-2654

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

        注释:$1le Vle 5cdot 10^4$,$1le E le 10^5$,$1le val_ile 100$。

          想法:乍一看最小生成树,然后直接gg,没有更好的处理方法。用什么样的方法可以将白边的边数恰好为need且边权和最小?EdwardFrog讲课的时候就提出了这样的方法:二分出往白边上加上多少权值。首先,统一的往白边上加权值会使得加权后的最小生成树中白边个数下降,这是单调的,我们可以用二分实现。二分的同时求出加权后的使得最小生成树中白边恰好有need条的边权val,求出最小生成树后将val*need减掉即可。

        最后,附上丑陋的代码... ...

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <stdlib.h>
    using namespace std;
    struct E
    {
    	int a,b,v,c,d;
    }e[100050];
    bool cmp(const E &x,const E &y)
    {
    	if(x.c==y.c) return x.d<y.d;
    	return x.c<y.c;
    }
    int n,m,k,fa[50050],reimu;
    int find(int x)
    {
    	return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    void init(int x)
    {
    	for(int i=0;i<=n;i++)
    		fa[i]=i;
    	for(int i=1;i<=m;i++)
    	{
    		if(e[i].d==0)
    		{
    			e[i].c=e[i].v+x;
    		}
    		else
    			e[i].c=e[i].v;
    	}
    	sort(e+1,e+m+1,cmp);
    }
    int check(int mn)
    {
    	reimu=0;
    	int re=0,nowe=0;
    	init(mn);
    	for(int i=1;i<=m;i++)
    	{
    		int x=e[i].a,y=e[i].b;
    		int dx=find(x),dy=find(y);
    		//printf("%d %d",x,y);
    		if(dx!=dy)
    		{
    			reimu+=e[i].c;
    			fa[dx]=dy;
    			if(!e[i].d)
    				re++;
    			nowe++; 
    			if(nowe==n-1)
    			{
    				break;
    			}
    		}
    	}
    	return re;
    }
    int main()
    {
    	scanf("%d%d%d",&n,&m,&k);
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%d%d%d%d",&e[i].a,&e[i].b,&e[i].v,&e[i].d);
    	}
    	int l=-1000,r=1000,ans;
    	while(l<r)
    	{
    		int mid=(l+r)>>1;
    		int z=check(mid);
    		if(z<k)r=mid;
    		else l=mid+1,ans=reimu-k*mid;
    	}
    	printf("%d
    ",ans);
    }
    

        小结:二分显然是正确的。

  • 相关阅读:
    C#轻量级企业事务
    扩展方法
    JDK Environment Variable And Change default JDK
    AsyncTask简单获取网络图片的例子
    mysql基础
    Oracle基础操作
    java 中 colkection集合、迭代器、增强for、泛型
    centos7 解决 mysql_connect()不支持请检查mysql模块是否正确加载
    python 操作MySQL避坑1064
    面向对象学习
  • 原文地址:https://www.cnblogs.com/ShuraK/p/9023664.html
Copyright © 2020-2023  润新知