首页 > 其他分享 >【CF1120D】Power Tree(建图,差分,最小生成树)

【CF1120D】Power Tree(建图,差分,最小生成树)

时间:2022-10-28 20:04:00浏览次数:52  
标签:一个点 Power int 点权 Tree Alice 差分 建图 节点

题面

题意有点难懂。

主要是洛谷给的翻译太zz了。

大概的意思是:

给定一棵 \(n\) 个点的有根树,\(1\) 为根,每一个点有一个代价 \(c_i\)。

然后有两个人 Alice 和 Bob 在玩游戏。

在第一阶段,Alice 会购买树上的一些点,购买一个点的代价是 \(c_i\)。

在第二阶段,Bob 将给树的所有叶子节点设置一个点权。

在第三阶段,Alice 可以选择他在第一阶段购买的一些点。对于他选择的每一个点 \(u\),他可以让 \(u\) 子树内的所有叶子节点的点权加上他任意指定的一个整数 \(x\)。

你需要帮 Alice 选择购买一些点,使得不管在第二阶段 Bob 怎样设置叶子节点的点权,总有一种方法使得 Alice 在第三阶段把所有叶子节点的点权归零,而且购买花费的代价尽量小。

题解

很巧妙的一种方法。

首先我们可以把叶子节点按 dfs 序抽象成一个序列,不妨设这个序列长 \(k\)。

那么控制一棵子树内的叶子节点的点权等同于控制序列一段区间的点权。

全体置零的要求和区间加的操作容易联想到差分数组,不妨设差分数组 \(b_i=a_i-a_{i-1}\),\(a_0=0\)。

对于操作区间 \([l,r]\) 加 \(x\),就可以看作是 \(b_l\) 加 \(x\),\(b_{r+1}\) 减 \(x\),那么我们就得新建出一个虚点 \(k+1\)。

对于要求全体置零,就可以看做是要求 \(\forall i\in[1,k],b_i=0\)。

发现每次操作后差分数组的总和不会变,所以为了达到要求,必须把所有的值转移到 \(b_{k+1}\) 上去。

对于操作区间 \([l,r]\) 加 \(x\),我们可以连边 \((l,r+1)\),边权为 \(x\)。

不难发现当且仅当两个点联通时,才能把一个点的 \(b\) 值转移到另一个点上去,且代价为边权和(注意代价与 \(b\) 值大小无关,所以这道题不是用网络流)。

所以题目的要求就是所有的点都要和 \(k+1\) 联通,然后问最小代价。

那么这就是一个最小生成树能解决的事情了。

至于输出所有可能在最优方案中的点,也就是输出所有可能出现在最小生成树中的边,可以直接在 kruskal 的过程中判断一下就好了。(我差点写了最小生成树的树剖)

代码如下:

#include<bits/stdc++.h>

#define N 200010
#define ll long long

using namespace std;

struct Edge
{
	int u,v,w,id;
	Edge(){};
	Edge(int a,int b,int c,int d){u=a,v=b,w=c,id=d;}
}e[N];

int n,m,c[N],fa[N];
int cnt,head[N],nxt[N<<1],to[N<<1];
int idx,lp[N],rp[N],size[N];
bool vis[N];
int num;
ll ans;

void adde(int u,int v)
{
	to[++cnt]=v;
	nxt[cnt]=head[u];
	head[u]=cnt;
}

void dfs(int u,int fa)
{
	bool leaf=true;
	for(int i=head[u];i;i=nxt[i])
	{
		int v=to[i];
		if(v==fa) continue;
		leaf=0;
		dfs(v,u);
		if(!lp[u]) lp[u]=lp[v];
		rp[u]=rp[v];
	}
	if(leaf) lp[u]=rp[u]=++idx;
	e[++m]=Edge(lp[u],rp[u]+1,c[u],u);
}

bool cmp(Edge a,Edge b)
{
	return a.w<b.w;
}

int find(int x)
{
	return x==fa[x]?x:(fa[x]=find(fa[x]));
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&c[i]);
	for(int i=1;i<n;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		adde(u,v),adde(v,u);
	}
	dfs(1,0);
	sort(e+1,e+m+1,cmp);
	idx++;
	for(int i=1;i<=idx;i++) fa[i]=i;
	for(int l=1,r;l<=m;l=r+1)
	{
		r=l;
		while(r+1<=m&&e[r].w==e[r+1].w) r++;
		for(int i=l;i<=r;i++)
		{
			int a=find(e[i].u),b=find(e[i].v);
			if(a!=b)
			{
				num++;
				vis[e[i].id]=1;
			}
		}
		for(int i=l;i<=r;i++)
		{
			int a=find(e[i].u),b=find(e[i].v);
			if(a!=b)
			{
				fa[a]=b;
				ans+=e[i].w;
			}
		}
	}
	printf("%lld %d\n",ans,num);
	for(int i=1;i<=n;i++)
		if(vis[i]) printf("%d ",i);
	return 0;
}

标签:一个点,Power,int,点权,Tree,Alice,差分,建图,节点
From: https://www.cnblogs.com/ez-lcw/p/16837312.html

相关文章

  • 【BZOJ4987】Tree(树形dp)
    题意:给你一棵\(n\)个节点的树找出\(k\)个不同的点\(a_1,a_2,\cdots,a_k\),使得\(\sum\limits_{i=1}^{k-1}dis(a_i,a_{i+1})\)最小。首先有个容易想到的性质:这\(k......
  • TreeMap
    (1)TreeMap跟TreeSet底层原理一样,都是红黑树结构的。(2)由键决定特性:不重复、无索引、可排序。(3)可排序:对键进行排序。(4)注意:默认按照键的从小到大进行排序,也可以自己规定键的......
  • 【BZOJ2212】【POI2011】【XSY2014】Tree Rotation(线段树合并)
    输入格式真的毒瘤权值线段树合并。我们先对每一个叶子建一棵权值线段树,并把它自己的权值插入到里面。我们不妨设原树中当前节点为\(u\),爸爸\(fa\),左儿子\(lc\),右儿子......
  • 【ARC069F】Flags(2-SAT,Tarjan,线段树优化建图)
    注意:本题的点数可以相比题解优化一半。首先先二分答案。然后判断能否使得两两旗子之间的距离都大于\(mid\)。然后发现这是一个2-SAT问题。2-SAT问题:通俗地说,有\(......
  • 【AGC023F】01 on Tree(树上一类全序问题)
    显然如果没有树的限制,我们优先选\(0\),然后选\(1\)。如果有了树的限制,我们考虑下面这么一种贪心方法:假设当前能够选的点的集合为\(S\)(初始时\(S\)只包含根),然后选出\(......
  • Hutool工具-TreeUtil封装树形结构数据,你用过了吗
    在开发过程中,必定会遇到树形结构的数据,一般都是后端直接从库里查询出来然后自定义方法去封装成树形树形返回给前端。其实Hutool工具类也提供了这个方法,这种方式使用起来也......
  • check power supply check cpu top
    lshw-cpower powersupplymwhhttps://www.eia.gov/energyexplained/electricity/electricity-in-the-us-generation-capacity-and-sales.php installpwrstatht......
  • GeckoFx (4)使用 treeview 展示 dom 数树
    GeckoFx(4)使用treeview展示dom数树使用DocumentCompleted事件,在页面加载完成后构建一个dom树使用treeview控件。treeHtml:treeview......
  • 树 Tree
    树的结构后继节点和该后继节点的父节点,(一个节点的后继节点是指,这个节点在中序遍历序列中的下一个节点,相应的,前驱节点是指这个节点在中序遍历序列中的上一个节点树的结......
  • The 2021 ICPC Asia Nanjing Regional Contest E.Paimon Segment Tree 区间合并线段树
    The2021ICPCAsiaNanjingRegionalContestE.PaimonSegmentTree区间合并线段树/维护矩阵乘法题目大意给定长度为的序列,要求支持区间加操作,同时对操作记录历史版本,查......