首页 > 其他分享 >color a tree poj2054

color a tree poj2054

时间:2023-05-05 21:34:31浏览次数:47  
标签:color 染色 sum tree poj2054 int nodes include 节点

color a tree(贪心)

题目描述
可以得到一个确定性的结论,最大值的结点一定是在父节点染色后立即染色。
但是此时依结论不好在复杂的情况正推,先考虑简单情况:
假如有权值x,y,z三个点,已知x,y一定一起染色,则有两种可能方案:

  1. 先x,y,再z,代价为X=x+2y+3z
  2. 先z,再x,y,代价为Y=2x+3y+z
    X-Y=2z-x-y,当z>(x+y)/2时,X-Y>0,即先z再x,y的方案更优。

由此推广有两个数组
\(a_1+a_2+……+a_n\)
\(b_1+b_2+……+b_m\)
每个均为一个点,数组内依次染色,考虑何时显然第一组点:

  • 先染\(a_i\),代价\(S_{ab}=\sum_{i=1}^n{a_i*i}+\sum_{i=n+1}^{n+m}{b_i*i}\);
  • 先染\(b_i\),代价\(S_{ba}=\sum_{i=1}^m{b_i*i}+\sum_{i=m+1}^{n+m}{a_i*i}\);

则此时显然第一组点的条件为\(S_{ab}<S_{ba}\),化简后得到\(\frac{\sum_1^n{a_i}}{n}\)<\(\frac{\sum_1^m{b_i}}{m}\),即第一组点的平均值小于第二组点的平均值。

在考虑剩余点染色顺序时,将两组点分别看作两个点,其权值分别是两组点内所有点的平均值。
最终做法:每次找出当前权值最大的非根节点,将其染色顺序排在紧随父节点之后的位置,然后将该点合并进父节点中,更新父节点的权值。直到将所有点都合并进根节点为止。
如果直接按上述算法做的话,最终的分值不太容易计算,我们可以在将点合并的时候,实时更新当前的权值和:

  • 最初所有点各自为一组,总分值是S=\(\sum_{i=1}^n{a_i}\)
  • 接下来每次会将两组点合并,将其中一组点接在另一组点的后面。比如两组点分别是\(x_i\)和\(y_i\),将\(y_i\)接在\(x_i\)后面,\(y_i\)中每个点所乘系数都要增加偏移量为\(x_i\)中点的个数,假设为k,合并后,总的权值直接加上\(k*\sum{y_i}\)即可

代码如下:

// Problem: 给树染色
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/117/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
#include<stack>
#include<vector>
#include<map>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;
typedef long long LL;
const int N=1010;
int n,root;
struct Node{
	int p,s,v;
	double avg;
}nodes[N];
int find(){
	int res=-1;
	double avg=0;
	for(int i=1;i<=n;i++){
		if(i!=root&&avg<nodes[i].avg){
			res=i;
			avg=nodes[i].avg;
		}
	}
	return res;
}
int main(){
	cin>>n>>root;
	int ans=0;
	for(int i=1;i<=n;i++){
		cin>>nodes[i].v;
		nodes[i].avg=nodes[i].v;
		nodes[i].s=1;
		ans+=nodes[i].v;
	}
	for(int i=0;i<n-1;i++){
		int a,b;
		cin>>a>>b;
		nodes[b].p=a;
	}
	for(int i=0;i<n-1;i++){
		int p=find();
		int father=nodes[p].p;
		ans+=nodes[p].v*nodes[father].s;
		nodes[p].avg=-1;
		for(int j=1;j<=n;j++){
			if(nodes[j].p==p){
				nodes[j].p=father;
			}
		}
		nodes[father].v+=nodes[p].v;
		nodes[father].s+=nodes[p].s;
		nodes[father].avg=(double)nodes[father].v/nodes[father].s;
	}
	cout<<ans<<endl;

	return 0;
}

标签:color,染色,sum,tree,poj2054,int,nodes,include,节点
From: https://www.cnblogs.com/viewoverlooking/p/17375413.html

相关文章

  • 【VBA】树控件TreeView的学习(一)
    哈喽,手机边亲爱的你还好吗?我是默默给大家分享Access知识的will。大家2022年快乐,从今天开始我们来讲一下树控件。树控件在我们的开发中是经常用的到的控件也是一个重点,我会从最简单的讲起,一点点,一点点的加上难度,最后我们把BOM挂到树上,顺便讲一下BOM。我会先发一篇文章再出一个视频。......
  • SPOJ COT3 Combat on a tree
    简要题意给定一棵有根树,初始有黑点白点。两人交替操作,每次选择一个白点,将这个点到根路径上所有点染黑,选不了则输。求先手能否必胜;如果能,给出第一步可能的所有走法。数据范围:\(1\len\le10^5\)。题解小清新题。难度不配黑题。进行一次操作以后,这个点到根路径上所有点两侧的子......
  • POJ 3321 Apple Tree(树状数组)
    AppleTreeTimeLimit: 2000MS MemoryLimit: 65536KTotalSubmissions: 21635 Accepted: 6573DescriptionThereisanappletreeoutsideofkaka'shouse.Everyautumn,alotofappleswillgrowinthetree.Kakalikesappleverymuch,sohehasbeen......
  • Odoo14 Tree视图创建按钮后面增加按钮
    1.继承ListView.buttons,在其按钮后面增加我们自定义的按钮,通过widget的一些属性去判断按钮的显示<templatesid="list_import_shipping_button_create"xml:space="preserve"><tt-extend="ListView.buttons"><tt-jquery="div.o_list_buttons&......
  • 1159 Structure of a Binary Tree + 根据前序和中序构建二叉树+ 层序遍历模板复习
    题目链接:https://pintia.cn/problem-sets/994805342720868352/exam/problems/1478635126488367104唉,今天的bug出在了下面这条语句。if(tree[root_key].left*tree[root_key].right<0)full_tree=false;我写成了full_tree=!(tree[root_key].left*tree[root_key].rig......
  • AtCoder Regular Contest 125 F Tree Degree Subset Sum
    洛谷传送门AtCoder传送门首先将度数\(-1\)。设\(f_i\)为体积为\(i\)至多能用几个物品凑出来,\(g_i\)为至少。我们现在要证明一个东西:\(x\in[g_i,f_i]\),\((i,x)\)合法。首先若\((s,x)\)合法,那么必须满足\(s-x\in[-z,z-2]\),其中\(z=\sum\limits_{i=1}......
  • Codeforces 280C Game on Tree
    设\(p_i\)为\(i\)涂色或不涂色,\(1\)为涂,\(0\)为不涂,答案即为\(E[\sum_{i=1}^np_i]\)然后转化一下柿子:\(\sum_{i=1}^nE[p_i]\),这就很好求了,单独求每个点\(E[p_i]\)的值就行了考虑对于\(u\)点,\(p_u=1\),即能被涂需要满足其祖先都比其晚涂色假设现在有一个序列里面......
  • CF911F Tree Destruction
    题意:给你一棵\(n\)个结点组成的树,你需要对树进行\(n-1\)次操作,一次操作包含如下的步骤:选择两个叶子结点将这两个结点之间简单路径的长度加到答案中从树上删去两个叶子结点之一初始答案为\(0\),显然在\(n-1\)次操作之后树上只剩下一个结点。计算最大的答案,并构造一组......
  • Atcoder Grand Contest 059 E - Grid 3-coloring(转化+思维)
    首先先是一步很猛的操作——将三染色视作构造一个矩阵使得相邻元素相差\(1\)且每个元素\(\bmod3\)的值就等于其颜色。证明是显然的,我们按从上到下从左到右的顺序填数,可以归纳证明,对于一个相邻格子颜色互不相同的矩阵的填数方案,处于斜对角的两个格子上写的数要么差\(2\),要么......
  • odoo tree下直接编辑, 免跳转form
      <recordid="mypartner_tree_view"model="ir.ui.view"><fieldname="name">Mypartner清单</field><fieldname="model">mypartner</field><fieldname="arch&......