zoukankan      html  css  js  c++  java
  • 【BZOJ3252】攻略(长链剖分,贪心)

    【BZOJ3252】攻略(长链剖分,贪心)

    题面

    BZOJ
    给定一棵树,每个点有点权,选定(k)个叶子,满足根到(k)个叶子的所有路径所覆盖的点权和最大。

    题解

    一个假装是对的贪心:
    每次选择最大的路径,然后将路径上所有点的权值清零。
    那么我们可以用长链剖分来实现这个贪心。
    链长改为最大的路径权值和,这样子把每条重链的权值丢进一个堆里面取(k)次即可。
    正确性自己(YY)一下,发现是对的

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define ll long long
    #define MAX 200200
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    priority_queue<ll> Q;
    struct Line{int v,next;}e[MAX<<1];
    int h[MAX],cnt=1;
    inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
    int a[MAX],n,K,hson[MAX];
    ll ms[MAX],ans;
    void dfs1(int u)
    {
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;dfs1(v);
    		if(ms[v]>ms[hson[u]])hson[u]=v;
    	}
    	ms[u]+=a[u]+ms[hson[u]];
    }
    void dfs2(int u,int tp)
    {
    	if(u==tp)Q.push(ms[u]);
    	if(hson[u])dfs2(hson[u],tp);
    	for(int i=h[u];i;i=e[i].next)
    		if(e[i].v!=hson[u])dfs2(e[i].v,e[i].v);
    }
    int main()
    {
    	n=read();K=read();
    	for(int i=1;i<=n;++i)a[i]=read();
    	for(int i=1,x,y;i<n;++i)x=read(),y=read(),Add(x,y);
    	dfs1(1);dfs2(1,1);
    	while(K&&!Q.empty())ans+=Q.top(),Q.pop(),--K;
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    ES 入门记录之 match和term查询的区别
    ElasticSearch 学习记录之Text keyword 两种基本类型区别
    ES 记录之如何创建一个索引映射,以及一些设置
    娱乐至死 读书笔记
    ES 入门之一 安装ElasticSearcha
    王二的经济学故事 读书笔记
    redis特性 存储 API 集群 等
    Linux 卸载 openjdk
    Linux 下面解压.tar.gz 和.gz文件解压的方式
    本地连接 vmware服务器
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9471412.html
Copyright © 2011-2022 走看看