zoukankan      html  css  js  c++  java
  • P2619 [国家集训队2]Tree I

    P2619 [国家集训队2]Tree I

    整体二分(~~~~~~~~)个鬼嘞

    汗,此整体非彼整体2333

    这是一道二分题不假。而是将整体的位置进行二分

    偶然时看到这个题。

    百思不得其解,然后网上一查。恍然大悟呀

    大体就是说(使用克鲁斯卡尔)。如果选了多于need条白边,就将所有白边的边权加上一个数,如果小于need条,就将所有白边的权值减去一个数

    然后发现,这是具有单调性的。所以我们二分这个减去或加上的数就可以。

    不过为什么不直接贪心的选取need条白边呢?

    钟梓俊
    貌似网上的题解现在还没有给出具体的证明和数据,那么我就来发一下。
    如果我们选了 needneed 条较小的白边,那么可能会影响黑边的选择。下面是一组可以卡掉直接选need条白边的数据,如下。

    3 4 1
    0 1 5 0
    1 2 6 0
    0 1 2 1
    1 2 9 1
    
    #include<cstdio> 
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using std::sort;
    const int maxn=101000;
    struct node
    {
    	int p1,p2;
    	int weight;
    	int c;
    	bool operator <(const node &a)const 
    	{
    		if(weight==a.weight)	return c<a.c;
    		return weight<a.weight;
    	}
    };
    node line[maxn];
    node copy[maxn];
    int f[maxn];
    int v,e,N,ans;
    int find(int x)
    {
    	return f[x] == x ? x : f[x]=find(f[x]) ;
    }
    bool check(int val)
    {
    	ans=0;
    	memset(f,0,sizeof(f));
    	for(int i=0;i<=v;i++)	f[i]=i;
    	for(int i=1;i<=e;i++)
    	{
    		copy[i]=line[i];
    		if(!line[i].c)	copy[i].weight+=val;
    	}//整体加上一个数
    	sort(copy+1,copy+1+e);
    	int get=0,tot=0,i=1;
    	while(get<v-1)//普通的克鲁斯卡尔
    	{
    		int f1=find(copy[i].p1),f2=find(copy[i].p2);
    		if(f1!=f2)
    		{
    			get++;
    			ans+=copy[i].weight;
    			f[f1]=f2;
    			if(!copy[i].c)	tot++;
    		}
    		i++;
    	}
    	return tot>=N;
    }
    int main()
    {
    	scanf("%d%d%d",&v,&e,&N);
    	for(int i=1;i<=e;i++)
    		scanf("%d%d%d%d",&line[i].p1,&line[i].p2,&line[i].weight,&line[i].c);
    	int l=-101,r=101,end;
    	while(l<=r)
        {
            int mid=(l+r)/2;
            if(check(mid))
    			l=mid+1,end=mid;
            else r=mid-1;
        }
        check(end);
        printf("%d
    ",ans-N*end);//最后减去
    }
    
  • 相关阅读:
    ELK 收集 K8S (containerd 容器运行时) 二
    EFK 收集 Docker 日志
    ELK 收集 Docker 日志
    ELK 收集 K8S (containerd 容器运行时) 三
    Java 基础(Stream APl)
    Java 基础(方法引用 Method References)
    Java 基础(Lambda表达式 和 函数式 Functional 接口)
    Java 基础(Stream APl) 二
    ELK 收集 K8S (containerd 容器运行时) 一
    部署 Harbor 2.4.1
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9502538.html
Copyright © 2011-2022 走看看