• bzoj2654:tree


    传送门

    wqs二分果题
    就是切线对应多个点有点烦,别的很好想
    当切线对应多个点时,就取横坐标最小的决策点,最后取横坐标最大的决策点求答案。
    代码:

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    #define rg register
    void read(int &x){
    	char ch;bool ok=0;
    	for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
    	for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    	if(ok)x=-x;
    }
    const int maxn=1e5+10;
    int f[maxn],n,m,k,ans,num;
    struct oo{int x,y,z,id;}a[maxn],g[maxn];
    bool cmp(oo a,oo b){return a.z==b.z?a.id>b.id:a.z<b.z;}
    int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
    bool check(int now){
    	for(rg int i=1;i<=n;i++)f[i]=i;
    	int tot=0,sum=0;num=0;
    	for(rg int i=1;i<=m;i++)g[++tot]=a[i],g[tot].z=!a[i].id?g[tot].z-now:g[tot].z;
    	sort(g+1,g+m+1,cmp);
    	for(rg int i=1;i<=m;i++)
    		if(find(g[i].x)!=find(g[i].y)){
    			sum+=(g[i].id==0),num+=g[i].z;
    			f[find(g[i].x)]=find(g[i].y);
    		}
    	return sum<=k;
    }
    int main(){
    	read(n),read(m),read(k);
    	for(rg int i=1,x,y,z,op;i<=m;i++){
    		read(x),read(y),read(z),read(op);x++,y++;
    		a[i]=(oo){x,y,z,op};
    	}
    	int l=-105,r=105;
    	while(l<=r){
    		int mid=(l+r)>>1;
    		if(check(mid))l=mid+1,ans=num+mid*k;
    		else r=mid-1;
    	}
    	printf("%d
    ",ans);
    }
    
    
  • 相关阅读:
    Linux 常用命令
    silky微服务简介
    okhttp中的Builder模式
    Assert in C#&Java
    Abstract类中使用@Autowire
    @Scope("prototype") bean scope not creating new bean
    【转】centos系统查看cpu内存等情况
    hdu 7013 String Mod 题解
    牛客 11259 H Scholomance Academy 题解
    bzoj 2151 种树 题解
  • 原文地址:https://www.cnblogs.com/lcxer/p/11143242.html
Copyright © 2020-2023  润新知