zoukankan      html  css  js  c++  java
  • 洛谷.2619.[国家集训队2]Tree I(带权二分 Kruskal)

    题目链接

    (Description)

    给定一个无向带权连通图,每条边是黑色或白色。求一棵最小权的恰好有K条白边的生成树。

    (Solution)

    Kruskal是选取最小的n-1条边。而白边数有限制,考虑为其设额外边权C。
    随着C增大,选的白边数应是不增的。可以二分求一个C值使得此时恰好选择K条边。选取时应优先选白边,因为多了还可以用黑边替换,少了只能减少C。
    可能的问题是,C=mid时白边数>K,C=mid+1时白边数<K,因为有很多黑边与+mid后的白边权值想等。可以用这些黑边替换掉多余的白边,所以答案应是减K*mid(保留黑边)。

    //404ms	3.36MB
    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    //#define gc() getchar()
    #define MAXIN 100000
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    const int N=5e4+5,M=1e5+5;
    
    int n,m,K,fa[N],Ans;
    char IN[MAXIN],*SS=IN,*TT=IN;
    int read();
    struct Edge
    {
    	int fr,to,val,col;
    	inline void Init(){
    		fr=read()+1, to=read()+1, val=read(), col=read();
    	}
    	bool operator <(const Edge &x)const{
    		return val==x.val?col<x.col:val<x.val;
    	}
    }e[M];
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    int GetFa(int x){
    	return x==fa[x]?x:fa[x]=GetFa(fa[x]);
    }
    bool Check(int x)
    {
    	for(int i=1; i<=m; ++i) if(!e[i].col) e[i].val+=x;
    	for(int i=1; i<=n; ++i) fa[i]=i;
    	std::sort(e+1,e+1+m);
    	int sum=0, cnt=0;
    	for(int i=1,k=0,r1,r2; i<=m; ++i)
    	{
    		if((r1=GetFa(e[i].fr))==(r2=GetFa(e[i].to))) continue;
    		fa[r1]=r2, sum+=e[i].val;
    		cnt+=e[i].col^1;
    		if(++k+1==n) break;
    	}
    	for(int i=1; i<=m; ++i) if(!e[i].col) e[i].val-=x;
    	if(cnt<K) return 0;
    	Ans = sum-K*x;//不能取min!
    	return 1;
    }
    
    int main()
    {
    	n=read(),m=read(),K=read();
    	for(int i=1; i<=m; ++i) e[i].Init();
    	Ans=m*101; int l=-101,r=101,mid;
    	while(l<=r)//l==r时要Check一遍(或者结束时)
    		if(Check(mid=l+r>>1)) l=mid+1;
    		else r=mid-1;
    //	Check(l);
    	printf("%d",Ans);
    
    	return 0;
    }
    
  • 相关阅读:
    树莓派使用MJPG-Streamer实现网络监控
    树莓派USB摄像头与camera模块对比
    机器人教程
    win10开始菜单打不开怎么办 win菜单键没反应解决办法
    solr查询语法
    Substance 6 设置 watermark(水印)
    在SWING里嵌入SWT的组件
    solr 5.5.1安装并配置中文分词IKAnalyzer
    [简单]docx4j常用方法小结
    Java串口通信详解
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9162351.html
Copyright © 2011-2022 走看看