poj 2054 Color a Tree(贪心)

# include <stdio.h>
# include <algorithm>
# include <string.h>
using namespace std;
int father[1010];
int next[1010];//当前集合的下个元素(包括i)
int pre[1010];//当前集合的上个元素(包括i)
int num[1010];//num[i]当前集合储存的点的个数(包括i)
int vis[1010];
int sum[1010];//当前集合的元素和
int c[1010];//点的花费
int n,r;
int find_max()//找到当前权值最大的集合
{
    double max=0;
	int bh=-1;
	for(int i=1;i<=n;i++)
	{
		if(max<(sum[i]*1.0)/num[i]&&!vis[i])
		{
			max=(sum[i]*1.0)/num[i];
			bh=i;
		}
	}
	return bh;
}
void uni(int x)//联合
{
	int i;
	for(i=father[x];pre[i]!=-1;i=pre[i])//找到父元素所在的集合
	{}
		sum[i]+=sum[x];
	    num[i]+=num[x];
	for(i=father[x];next[i]!=-1;i=next[i])//找到父元素所在集合的底元素
	{}
	next[i]=x;
	pre[x]=i;
	vis[x]=1;

}
int main()
{
	int i;
	while(~scanf("%d%d",&n,&r),n+r)
	{
		for(i=1;i<=n;i++)
		{
			scanf("%d",&c[i]);
			vis[i]=0;
			sum[i]=c[i];
			pre[i]=next[i]=-1;
			num[i]=1;
		}
		for(i=1;i<n;i++)
		{
			int a,b;
			scanf("%d%d",&a,&b);
			father[b]=a;
		}
		int d;
		vis[r]=1;//初始点
		while(1)
		{
			d=find_max();
			if(d==-1)
				break;
			uni(d);
		}
		int ans=0,t=1;
		for(i=r;i!=-1;i=next[i])
		{
			ans+=c[i]*t;
			t++;
		}
		printf("%d\n",ans);
	}
    return 0;
}

时间: 2024-10-12 23:15:05

poj 2054 Color a Tree(贪心)的相关文章

POJ 2054 Color a Tree#贪心(难,好题)

题目链接 代码借鉴此博:http://www.cnblogs.com/vongang/archive/2011/08/19/2146070.html 其中关于max{c[fa]/t[fa]}贪心原则,此博有很好的解释:http://www.cnblogs.com/rainydays/p/3271277.html 在此引用其中几段话: 试想,如果没有父节点排在节点之前的限制,那么这个题目非常简单,只需要将结点按照权值从大到小排列即可.加上了这个限制之后,如果权值最大的那个节点一旦满足了条件(父节点

poj 2054 Color a Tree 据说是贪心

Color a Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 7112   Accepted: 2438 Description Bob is very interested in the data structure of a tree. A tree is a directed graph in which a special node is singled out, called the "root&qu

hdu 1055 &amp; poj 2054 Color a Tree 树&amp;贪心 找最大费用点和父节点合并

Color a Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 7144 Accepted: 2458 Description Bob is very interested in the data structure of a tree. A tree is a directed graph in which a special node is singled out, called the "root"

poj 2054 Color a Tree

很有意思的一道贪心题,自己没想出来,理解了一下别人的思路 参考:http://www.cnblogs.com/yu-chao/archive/2012/02/19/2358565.html http://my.oschina.net/locusxt/blog/210536 题目大意:给你一颗树,树上每个节点都有自己的权值,现在要把这棵树上的所有节点染上颜色,每染一个节点需要一个单位的时间,染一个点的花费是该点的权值乘以当前时间(时间从1开始).规定在染当前点之前,必须先染他的父亲节点,求最小的花

poj 2054 Color a Tree(贪婪)

# include <stdio.h> # include <algorithm> # include <string.h> using namespace std; int father[1010]; int next[1010];//当前集合的下个元素(包含i) int pre[1010];//当前集合的上个元素(包含i) int num[1010];//num[i]当前集合储存的点的个数(包含i) int vis[1010]; int sum[1010];//当前

HDU 1055 Color a Tree

题目:Color a Tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=1055 题意:给一棵树,要给树上每一个结点染色,第i 个结点染色需要代价为:t * w[i] (t 表示i 结点是第几个染色的),还有一个前提是:要给i 结点染色,必须先给i 结点的父结点染色(根结点随便染). 思路: 贪心. 假定当前未染色的结点中权值最大的是A结点,如果A结点上方都染完色,那么现在一定是对A结点进行染色. 理解如下: 假设在上述情况下先对其他结点染色,在

POJ 2965-The Pilots Brothers&#39; refrigerator(贪心+枚举)

The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19464   Accepted: 7462   Special Judge Description The game "The Pilots Brothers: following the stripy elephant" has a quest where a player needs to o

codeforces219C - Color Stripe DP+贪心

题意:给你n,k,大意就是说给你一个已经涂满颜色长为n的字符串,现有k种颜色可以选择,问你最少要改变多少个箱子的颜色使得相邻箱子之间颜色不同. 解题思路:当k = 2 时单独讨论,不能用贪心,其余情况都可贪心得到. 解题代码: 1 // File Name: 219c.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月26日 星期六 15时45分56秒 4 5 #include<vector> 6 #include<list>

hdu 4603 Color the Tree 2013多校1-4

这道题细节真的很多 首先可以想到a和b的最优策略一定是沿着a和b在树上的链走,走到某个点停止,然后再依次占领和这个点邻接的边 所以,解决这道题的步骤如下: 预处理阶段: step 1:取任意一个点为根节点,找出父子关系并且对这个树进行dp,求出从某个节点出发往下所包含的所有边的权值总和  复杂度O(n) step 2:从tree dp 的结果中计算对于某个节点,从某条边出发所包含的边的综合,并且对其从大到小进行排序 复杂度O(n*logn) step 3:dfs求出这颗树的欧拉回路,以及每个点的